In Julia 1.7.2 multiplication of 3037000691 and 3037000693 returns the negative product -9223370870501072753. The product I expected is 9223373203208478863.
function m(a::BigInt, b::BigInt)::BigInt
a * b
end
This function gives the same negative result.
Any ideas on how to get the correct answer in Julia 1.7.2 to 3037000691 * 3037000693 ?
P.S.
I did run into this issue doing some math on (big) twin prime numbers.
Julia’s integers are machine integers with defined overflow behavior - the negative result is expected. Using BigInt (like shown above by @jishnub) uses the GMP library in the background, which has arbitrary precision arithmetic which does not have overflow.
Do you have a runnable example where one of the two behaviors I described is not as expected?
Thanks for your answer. How should I (re)write the function to return the correct answer? I would like to use the arguments 037000691 and 3037000693 instead of big(037000691) and big(3037000693).
Without knowing anything more about your use case, except that you want to multiply two numbers, the only useful advice is to use big or some other extended precision type.
Tell us more about what you need these numbers for, maybe we can give better input. Maybe you don’t actually need to multiply, or maybe you can divide them by something first.
That still fails for large numbers, depending on their types:
julia> a = 10^18
julia> b = Int128(10)^38
julia> widen(a) * b
-2659601278039724572920059057942822912
julia> big(a) * b
100000000000000000000000000000000000000000000000000000000
Believe it or not the negative value is the correct (according to Int64 modular math), so expected by some.
Not it doesn’t:
julia> m(3037000691, 3037000693)
ERROR: MethodError: no method matching m(::Int64, ::Int64)
You probably also had such a function defined.
You additionally want:
julia> function m(a::Integer, b::Integer)
m(big(a), big(b))
end
and maybe also (to not convert to big twice):
julia> function m(a::Int64, b::Int64)
big(widen(a) * widen(b))
end