This is the code I will be using...
public class foo {
public static void main(String [] args){
int a = (int) Math.pow(2, 30);
double d = (a a - 1.0);
double f = (a a - 1);
System.out.println(d);
System.out.println(f);
}
}
The outputs are -2.147483649E9 and 2.147483647E9.
I do not understand why these values are printed out. It is my understanding that a a will exceed the limits of int and therefore will switch to being negative, however, f is positive. I would expect both to be negative but f would be fractional whilst d would be an double with a point 0 due to integer division.
CodePudding user response:
In the first case a a
overflows to Integer.MIN_VALUE
, then you switch to a double
context with -1.0
which gives a negative number (Integer.MIN_VALUE - 1
), since a double
can hold a number smaller than Integer.MIN_VALUE
.
In the second example you stay in an int
context, which means that a a
overflows to Integer.MIN_VALUE
, then subtracting 1 from that underflows and takes you back to Integer.MAX_VALUE
.
CodePudding user response:
Taking this apart step by step reveals the answer.
First, we observe that a a == Integer.MIN_VALUE
Ideone.com
demo.
Next, if the expression a a - 1.0
is evaluated, it is evaluated from left to right, i.e. it is equivalent to (a a) - 1.0
, which is equivalent to Integer.MIN_VALUE - 1.0
. Since the right hand side is a double
, Integer.MIN_VALUE
is converted to double
as well, and the result is negative.
Finally, if the expression a a - 1
is evaluated, it is equivalent to Integer.MIN_VALUE - 1
. The whole operation is done in the int
-space with ring arithmetic, and subracting 1
from the MIN_VALUE
evaluates to the MAX_VALUE
.