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