# 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
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> m(big(3037000691), big(3037000693))
9223373203208478863
``````

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)
end
``````
3 Likes

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

8 Likes

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

julia> big(a) * b
100000000000000000000000000000000000000000000000000000000
``````
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.

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

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

``````a * widen(b)
100000000000000000000000000000000000000000000000000000000
``````