3 votes

Je rencontre un problème avec l'utilisation d'une variable comme exposant dans Julia.

Je suis nouveau dans l'utilisation de Julia et je travaillais sur des problèmes d'exemple à partir de la base de données de Julia. aquí comme un moyen de se familiariser avec la langue. Pour décrire le problème spécifique auquel je suis confronté. J'essaie d'écrire du code pour la question 11 des problèmes de programmation qui me demande de calculer une somme. Je reproduis mon code ci-dessous. J'ai fixé une variable k à 1 et la formule doit trouver la valeur de -1 à la puissance de k + 1. Lorsque k = 1, elle devrait calculer le résultat comme -1 au carré, ce qui devrait être 1, mais elle renvoie -1. Je ne suis pas sûr de ce qui ne va pas ici. Aidez-moi à comprendre mon erreur ?

function computeequation()
    result = 0
    for k = 1:1000000
        result = result + ((-1^(k+1))/((2 * k) - 1))
    end
    return 4 * result
end

5voto

giordano Points 1289

Ceci est commun à plusieurs langages de programmation, pas seulement à Julia : l'exponentiation a une priorité plus élevée que la soustraction ou la négation. Pour Julia, vous pouvez voir le tableau de la liste de la précédence des opérateurs ici : https://docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity-1 .

Pour cette raison, -1^2 ne produit pas ce à quoi vous pouvez naïvement vous attendre :

julia> -1^2
-1

Pour remplacer la préséance par défaut, il suffit d'utiliser les parenthèses comme il convient :

julia> (-1)^2
1

Comme le suggère Lyndon White dans un commentaire pour visualiser la préséance des opérations dans une expression, il suffit de la citer.

julia> :(-1 ^ 2)
:(-(1 ^ 2))

julia> :((-1) ^ 2)
:((-1) ^ 2)

y dump pour voir l'intégralité AST :

julia> dump(:(-1 ^ 2))
Expr
  head: Symbol call
  args: Array{Any}((2,))
    1: Symbol -
    2: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol ^
        2: Int64 1
        3: Int64 2

julia> dump(:((-1) ^ 2))
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol ^
    2: Int64 -1
    3: Int64 2

Ici, vous pouvez noter que dans le premier cas, l'exponentiation est faite avant la négation, dans le second cas où les parenthèses sont utilisées, la négation vient avant l'exponentiation.

Une autre façon de voir comment une expression est abaissée dans Julia est d'utiliser la fonction de recherche. Meta.lower fonction :

julia> Meta.lower(Main, :(-1 ^ 2) )
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1  %1 = Core.apply_type(Base.Val, 2)
   %2 = (%1)()
   %3 = Base.literal_pow(^, 1, %2)
   %4 = -%3
      return %4
))))

julia> Meta.lower(Main, :((-1) ^ 2) )
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1  %1 = Core.apply_type(Base.Val, 2)
   %2 = (%1)()
   %3 = Base.literal_pow(^, -1, %2)
      return %3
))))

Pour votre problème particulier, vous pouvez faire

function computeequation()
    result = 0
    for k = 1:1000_000
        result = result + ((-1) ^ (k + 1))/((2 * k) - 1)
    end
    return 4 * result
end

2voto

Harsha Points 631

Je réponds à ma propre question. On dirait que l'ajout d'accolades autour du -1 résout le problème.

function computeequation()
    result = 0
    for k = 1:1000000
        result = result + (((-1)^(k+1))/((2 * k) - 1))
    end
    return 4 * result
end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X