了解Julia整数溢出行为

4

我来自Python/Matlab背景,希望更好地了解Julia的Int64溢出行为。

文档中可以看到:

在Julia中,超出给定类型可表示的最大值会导致环绕行为。

julia> x = typemax(Int64)
9223372036854775807

julia> x + 1
-9223372036854775808

我做了一些关于比typemax(Int64)大得多的数字的实验,但是我看到的行为与文档中描述的不一致。似乎并不总是只有一次包装。只允许单次包装吗?

julia> x = (10^10)^(10^10)
0
julia> x = 10^10^10^10 
1   # ??

julia> x = 10^10^10^10^10  
10  # I'd expect it to be 1? 1^10 == 1?

julia> x = 10^10^10^10^10^10 
10000000000  # But here 10^10 == 10000000000, so now it works?


julia> typemax(Int64) > 10^19
true
julia > typemax(Int64) > -10^19
true

有人能解释一下我所看到的行为吗?

编辑:

为什么9可以正确溢出,而10不行?

julia> 9^(10^14)
-1193713557845704703
julia> 9^(10^15)
4900281449122627585
julia> 10^(10^2)
0
julia> 10^(10^3)
0

Julia 0.5.0 (2016-09-19)

1个回答

5
你所看到的是PEMDAS运算顺序的结果,具体来说是指幂运算前的括号。这使得这些表达式从右向左求解。
julia> 10^(10^10) #happens to overflow to 0
0

julia> 10^(10^(10^10)) # same as 10 ^ 0
1

julia> 10^(10^(10^(10^(10^10)))) # same as x = 10^(10^(10^(10^(10000000000)))) -> 10^(10^(10^(0))) -> 10^(10^(1)) -> 10^ 10
10000000000

因此,这实际上只是一个算术问题。或者意识到您将拥有如此大的操作,以至于您从一开始就开始使用BigInt。


谢谢你的答案。这讲得很有道理。但是为什么10^(10^10)会溢出到0,而不是简单地绕过去呢?10^(10^11)也会溢出到0。如果你尝试9^(10^14)、9^(10^15),你会看到它们应该会绕过去的。 - Daniel
3
@dangom 它确实会循环。10^10^102^64 的倍数,因此刚好循环回到了 0。任何一个大的偶数指数都会发生类似的情况,比如 6^666 或者 14^5^5 - Fengyang Wang
@FengyangWang 确实。我没想到会是这样。感谢您的评论。10^100是2^64的倍数吗? - Daniel
4
考虑将每个数分解为质因数(例如10=2x5),然后进行扩展,即可得到答案。 - David P. Sanders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接