Multiplication of 2 positive numbers gives a negative product

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

This function gives the same negative result.

Any ideas on how to get the correct answer in Julia 1.7.2 to 3037000691 * 3037000693 ?

I did run into this issue doing some math on (big) twin prime numbers.

julia> m(big(3037000691), big(3037000693))

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).

You can always explicitly convert if you know you always want the answer as a BigInt

function m(a, b)
    big(a) * big(b)

The widen function can be used to generically convert to a wide enough type to store all possible arithmetic results. Ie widen(a) * widen(b).


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.

1 Like

Given Julia’s promotion rules, we could do “half the promotions” as we type:

big(a) * b
widen(a) * b
1 Like

In fact it gives a MethodError, unless you supply Big arguments, as @jishnub shows.

1 Like

widen(a) * b

That still fails for large numbers, depending on their types:

julia> a = 10^18
julia> b = Int128(10)^38

julia> widen(a) * b

julia> big(a) * b
1 Like

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))

and maybe also (to not convert to big twice):

julia> function m(a::Int64, b::Int64)
           big(widen(a) * widen(b))

You widened Int64, you should have widened Int128 in your example:

a * widen(b)