提问人:René 提问时间:5/1/2022 最后编辑:René 更新时间:5/2/2022 访问量:190
Julia 中 2 个正数的相乘得到负积
Multiplication of 2 positive numbers in Julia gives a negative product
问:
在 Julia 1.7.2 中,乘以并返回负积。我期望的产品是.3037000691
3037000693
-9223370870501072753
9223373203208478863
function m(a::BigInt, b::BigInt)::BigInt
a * b
end
此函数给出相同的否定结果。
关于如何在 Julia 1.7.2 中获得正确答案的任何想法?3037000691 * 3037000693
P.S.
我确实遇到了这个问题,在对(大)孪生素数进行一些数学运算时。
答:
6赞
Sash Sinha
5/1/2022
#1
尝试像这样调用函数:
julia> m(BigInt(3037000691), BigInt(3037000693))
9223373203208478863
或将您的功能更改为以下任一功能:
# TL;DR: Use this it is the fastest.
function m1(a::Int64, b::Int64)::Int128
Int128(a) * Int128(b)
end
function m2(a, b)::BigInt
BigInt(a) * BigInt(b)
end
function m3(a::Int64, b::Int64)::BigInt
BigInt(a) * BigInt(b)
end
请注意,从技术上讲,您只需要强制转换 a
或 b
,但我认为这会降低可读性。
用法示例:
julia> m1(3037000691, 3037000693)
9223373203208478863
julia> m2(3037000691, 3037000693)
9223373203208478863
julia> m3(3037000691, 3037000693)
9223373203208478863
在这种情况下,您应该使用 ,它仅使用 s,因为不可能将两个值相乘以溢出 :m1
Int128
Int64
Int128
julia> m1(9223372036854775807, 9223372036854775807) # Max val for Int64 squared.
85070591730234615847396907784232501249
通常,尽可能不使用 's 并明确说明函数中的类型将显著提高性能:BigInt
julia> using BenchmarkTools
julia> @benchmark m1(3037000691, 3037000693)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
Range (min … max): 0.049 ns … 7.780 ns ┊ GC (min … max): 0.00% … 0.00%
Time (median): 0.060 ns ┊ GC (median): 0.00%
Time (mean ± σ): 0.064 ns ± 0.078 ns ┊ GC (mean ± σ): 0.00% ± 0.00%
▁ █ ▃▆▃ ▂ ▁
▆█▆▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁███▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▄▆▄▁▁▁▁▁▁▁▁▁█ █
0.049 ns Histogram: log(frequency) by time 0.1 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
julia> @benchmark m2(3037000691, 3037000693)
BenchmarkTools.Trial: 10000 samples with 199 evaluations.
Range (min … max): 413.317 ns … 2.404 ms ┊ GC (min … max): 0.00% … 64.79%
Time (median): 507.080 ns ┊ GC (median): 0.00%
Time (mean ± σ): 1.957 μs ± 42.299 μs ┊ GC (mean ± σ): 26.95% ± 1.29%
▇▆█▇▆▅▅▄▄▃▂▂▁▂▁ ▂
█████████████████▇█▇▆▆▆▅▆▄▄▆▄▅▅▁▄▄▅▄▄▁▃▄▄▄▄▃▃▁▄▁▄▃▃▄▄▁▃▄▁▄▄▄ █
413 ns Histogram: log(frequency) by time 2.39 μs <
Memory estimate: 128 bytes, allocs estimate: 7.
julia> @benchmark m3(3037000691, 3037000693)
BenchmarkTools.Trial: 10000 samples with 199 evaluations.
Range (min … max): 414.774 ns … 2.487 ms ┊ GC (min … max): 0.00% … 64.53%
Time (median): 496.080 ns ┊ GC (median): 0.00%
Time (mean ± σ): 1.895 μs ± 41.026 μs ┊ GC (mean ± σ): 24.60% ± 1.20%
▄ ▂▁ ▂█▄
█▄██▇████▇▇▇▄▃▃▃▃▃▃▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▁▂▂ ▃
415 ns Histogram: frequency by time 1.14 μs <
Memory estimate: 128 bytes, allocs estimate: 7.
评论
0赞
René
5/1/2022
谢谢你的回答。我应该如何(重新)编写函数以返回正确答案?我想使用参数 037000691 和 3037000693 而不是 big(037000691) 和 big(3037000693)。
1赞
Sash Sinha
5/1/2022
这对你有用吗?
0赞
Antonello
5/2/2022
出于好奇,在用于数字插补的主要高级语言(例如R,Python,Matlab..)中,是否有任何语言可以自动执行大小写而不是溢出?
0赞
lungben
5/2/2022
Python 默认的整数类型对应于 Julia 的 BigInt,即 overflow-save,但速度非常慢。相比之下,Numpy 使用溢出的整数,类似于 Julia。
4赞
Przemyslaw Szufel
5/2/2022
#2
应该注意的是,问题中定义的函数不会提供负面结果(考虑到函数的语法,这将是非常错误的)。m
julia> m(3037000691, 3037000693)
ERROR: MethodError: no method matching m(::Int64, ::Int64)
Stacktrace:
[1] top-level scope
@ REPL[3]:1
Julia 不执行自动转换 from to 。总而言之,这意味着您已经(或刚刚)定义了它,并且为您的参数值调用了它。Int64
BigInt
m(::Int64, ::Int64)
m(::Any, ::Any)
[该怎么办在另一个公认的答案中描述]
评论