Overflow occurs with multiplication
Since expressions are evaluated from left to right, I would prefer your first solution (m2 = ...
).
Reasoning: Let's look at a slightly different example.
long g = Integer.MAX_VALUE * 2 * 2L;
This expression will evaluate to -4
since only the last multiplication casts the first expression to long
(which is -2
at this point in time, because both operands are int
). If you write
long g = Integer.MAX_VALUE * 2L * 2;
instead, g
will hold the expected value of 8589934588
since the first multiplication yields a result of type long
.
In this case -
long m = 24 * 60 * 60 * 1000 * 1000;
The right of the assignment is evaluated first. At right there is no long
type data. All are int
. So the JVM
try to fit the result in an int
then the overflow occurred.
And in the second case -
long m2 = 24L * 60 * 60 * 1000 * 1000;
long m3 = 24 * 60 * 60 * 1000 * 1000L;
Here one operand of the multiplication is long
. So other are prompted to long
automatically. The result is trying to fit to a long
. Finally the assignment is done with m2
and m3
.
And yes the associativity of multiplication from left to right - means the left operand is taken first. And Based on this fact I think in this scenario we should use -
long m2 = 24L * 60 * 60 * 1000 * 1000;
this statement, since at this statement the promotion to long
taken places earlier which reduces the risk of overflow.
I would use the m2
line instead of the m3
line.
Java evaluates the multiplication operator *
from left to right, so 24 * 60
is evaluated first.
It just so happens that 24 * 60 * 60 * 1000
(one 1000
) doesn't overflow, so that by the time you multiply by 1000L
(the second 1000
), the product is promoted to long
before multiplying, so that overflow doesn't take place.
But as you mentioned in your comments, more factors can cause overflow in the int
data type before multiplying the last long
number, yielding an incorrect answer. It's better to use a long
literal for the first (left-most) number as in m2
to avoid overflow from the start. Alternatively, you can cast the first literal as a long
, e.g. (long) 24 * 60 * ...
.
Multiplying works from left to right, and int * int
produces int
. So
24 * 60 * 60 * 1000 * 1000
is same as
(((24 * 60)* 60) * 1000) * 1000
which gives us
(((1440)* 60) * 1000) * 1000
(( 86400 ) * 1000) * 1000
( 86400000 ) * 1000
and finally because of integer overflow (since 86400000000
is too big for integer which max value is 2147483647
) result will be
500654080
You can eliminate integer overflow by using long
as one of arguments (int * long
and long * int
produces long
).
In this case you can do it at start like you did in case of m2
: 24L * 60
which will produce long
1440L
which again will be multiplied by int 60
producing new long
, and so on, producing only long
values.
m3
case works here because you are multiplying 86400000
by 1000L
which means that you are avoiding integer overflow since result will be long
.