在Julia中使用变量作为指数时遇到问题

Har*_*sha 3 exponent julia

我是Julia的新手,正在从这里开始研究一些示例问题,以作为一种掌握该语言的方法。描述我面临的具体问题。我正在尝试为编程问题中的问题11写一些代码,这需要我计算总和。我在下面复制我的代码。我将变量k设置为1,公式需要找到-1的值乘以k + 1的幂。当k = 1时,应将结果计算为-1平方,应为1,但返回-1。不知道这里出了什么问题。帮助我了解我的错误吗?

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

gio*_*ano 5

这是几种编程语言(不仅仅是Julia)所共有的:求幂的优先级高于减法或求反。对于Julia,您可以在此处查看运算符优先级的列表:https : //docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity-1

因此,-1^2不会产生您可能天真的期望:

julia> -1^2
-1
Run Code Online (Sandbox Code Playgroud)

为了覆盖默认优先级,请适当地使用括号:

julia> (-1)^2
1
Run Code Online (Sandbox Code Playgroud)

正如Lyndon White在评论中建议的那样,可视化表达式中运算的优先级的一种好方法是引用它

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

julia> :((-1) ^ 2)
:((-1) ^ 2)
Run Code Online (Sandbox Code Playgroud)

dump查看完整的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
Run Code Online (Sandbox Code Playgroud)

在这里,您可以注意到,在第一种情况下,取幂是在取反之前完成的;在第二种情况下,使用括号时,取反是在取幂之前进行的。

查看在Julia中如何降低表达式的另一种巧妙方法是使用该Meta.lower函数:

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
))))
Run Code Online (Sandbox Code Playgroud)

对于您的特定问题,您可以做

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