在Julia中处理大数
在Python中,我可以执行以下操作来获取在Julia中处理大数,julia,Julia,在Python中,我可以执行以下操作来获取N中所有数字的总和,其中N=99999**99999。可以使用sum(map(int,str(N)))获得总和 如何使用Julia查找N中所有数字的总和?您遇到了整数溢出。尝试使用BigInts julia> N=digits(big(99999)^99999) 499995-element Array{Int64,1}: 9 9 9 9 9 8 9 9 9 9 ⋮ 5 0 8 2 1 8 8 7 6 3
N
中所有数字的总和,其中N=99999**99999
。可以使用sum(map(int,str(N)))获得总和
如何使用Julia查找N中所有数字的总和?您遇到了整数溢出。尝试使用BigInt
s
julia> N=digits(big(99999)^99999)
499995-element Array{Int64,1}:
9
9
9
9
9
8
9
9
9
9
⋮
5
0
8
2
1
8
8
7
6
3
注意
julia> typemax(Int64)
9223372036854775807
它太小了,但是BigInt
s的大小是任意的big(i)
将i
转换为一个大(BigFloat
如果它是一个浮点,将BigInt
转换为一个整数)。Julia不会默认使用big/任意大小的数字,因为它们的速度非常慢,但如果调用它们,则大多数调度的类型稳定性将传播大类型,因此big(i)^j
最终将变大 总之,是这样
sum(digits(big(99999)^99999))
这个问题有点老了,但我发现一个有趣的性能改进对新用户很有用(或者更高级的用户可以解释),至少对那些使用Julia 1.5或更早版本的用户是有用的
默认情况下,Julia将“99999”强制转换为Int64
。然而,99999⁹⁹⁹⁹⁹ 是一个不适合Int64
变量(最多支持2)的大数字⁶³). 然后,您必须使用big(99999)
或等效的BigInt(99999)
(Python自动执行的操作)
可以写
sum(digits(big(99999)^99999))
而且它确实有效。进行一点基准测试,我发现:
- Python:
>>%timeit总和(map(int,str(99999**99999)))
每个回路4.9 s±5.43 ms(7次运行的平均值±标准偏差,每个回路1次)
- 朱莉娅:
我知道。Julia是“高于光速”、“快于C和Fortran”的语言。为什么它会(相当)慢于“海龟语言”Python?我们如何处理分配的巨大内存量?
让我们试试“pythonic”算法,用Julia重写:
julia> sum(map(x -> parse(Int32, x), collect(string(big(99999)^99999))))
我知道这听起来很奇怪,违反直觉,但数字说明一切。这是我的结果
- 朱莉娅(“Pythonic”方式):
备注。
%timeit
是一个IPython魔术@benchmark
是由(需要安装)实现的宏
- 在上一个Julia基准测试中,可以使用
Int8
映射字符串来改进内存分配,但时间相当相同
总之,它可以在Julia中完成,既可以使用简单但缓慢的代码,也可以使用冗长但快速的代码。但我无法确切解释原因。在Julia中,N=99999^99999给出了-ve值,它给出了负值?它给了我错误的答案,但仍然是肯定的。总结一下什么?这篇文章不清楚它是如何解决OP的问题的。最近在Julia 1.6中,digits
函数被优化为BigInt
,并且sum(digits(big(99999)^99999))
比你的“pythonic方式”稍微快一点。有趣。那么内存分配呢?
julia> sum(map(x -> parse(Int32, x), collect(string(big(99999)^99999))))
julia> @benchmark sum(map(x -> parse(Int32, x), collect(string(big(99999)^99999))))
BenchmarkTools.Trial:
memory estimate: 13.56 MiB
allocs estimate: 991
--------------
minimum time: 62.130 ms (0.00% GC)
median time: 63.111 ms (0.00% GC)
mean time: 63.183 ms (0.24% GC)
maximum time: 66.055 ms (0.68% GC)
--------------
samples: 80
evals/sample: 1