How does Java handle the intermediate values while evaluating a long arithmetic expression?

67 Views Asked by At

I was wondering how does Java handle the intermediate values while evaluating a mathematical expression specially when the intermediate values exceeds their storage size. For an example,

int a = 1103515245;
int x = 1013904223;
int c = 2531011;

x = (a*x + c) & 0x7FFFFFFF; //  to make sure x will remain a positive integer.

Now, my question is while computing a*x, its value exceeds integer range (even during the addition it could happen), how this is taken care by Java Compiler?

Thank you.

2

There are 2 best solutions below

5
that other guy On BEST ANSWER

JLS 15.17.1:

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format.

JLS 15.18.2:

If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format.

This is in contrast to C, which famously does not assume a two's-complement architecture and treats overflow of signed types as undefined behavior.

2
Michael Zinsmeister On

Each intermediate value has a type, unless you explicity cast it it will be the one that the intermediate calculation will produce so int * int will produce another int and int * float will produce another float and overflows of immediate values will happen accordingly. Such computations will essentially be deconstructed into something like

int a = 1103515245;
int x = 1013904223;
int c = 2531011;

x = a*x;
x = x + c;
x = x & 0x7FFFFFFF;

That's not really what the compiler does because it will produce JVM bytecode which operates on a stack machine but you can roughly imagine it as doing something closer to that code than to yours. There's nothing really magical about it. Overflows will happen just like they will in the decomposed operations i wrote in the code example. If you want to avoid overflows you need to cast one or both of the input values to some intermediate calculation to a larger data type like a long. Be careful here because just casting the result won't do the trick. Then it will first overflow and then cast the overflowed value.