Win a copy of Functional Reactive Programming this week in the Other Languages forum!

# ( int a = 2147483648 ) vs (int a = 2147483647 ; a=a+1 )

ashwin bhawsar
Ranch Hand
Posts: 62

What is happening behind the scene ?

int a=2147483648 ; // Compiler error, Out Of Range

But,

int a=2147483647;
a=a+1; // results into -2147483648

Ben Robertson
Greenhorn
Posts: 3
2147483648 looks suspiciously like the maximum integer that can be carried as 32-bit, hence, when you add 1 to it, it ticks over to the minimum integer.

Think of the Y2K bug and speedometers ticking over to 0

Matthew Brown
Bartender
Posts: 4568
9
Whenever you add something to a variable, it could potentially cause an overflow, because the compiler doesn't know what the value will be (it won't try to trace the value through multiple steps). So the second example has to be accepted by the compiler.

But the first example is definitely an error. The compiler knows the variable can't take that value. And if you really wanted it to be -2147483648, you could have written that. So it makes sense to not allow it.

Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15483
43
To really understand why an int goes from 2147483647 to -2147483648 when you add 1, you have to understand how integers work behind the scenes.

In Java (as in many other programming languages), integers are stored in two's complement format. The type int is 32 bits in Java. If you look at the bit pattern:

2147483647 = 01111111 11111111 11111111 11111111

If you add 1 to that, you get: 10000000 00000000 00000000 00000000

In two's complement, that is the number -2147483648.

Campbell Ritchie
Sheriff
Posts: 50208
79
Actually in Java™ it is slightly more complicated. You can see that the Java™ Language Specification only allows the number 2147438648 in one circumstance. So you are not really writing -2147483648. You are writing 217483648 and turning it negative with the - operator. You will notice the grammar shown does not include a - anywhere. So what you are doing with any number literal is supplying an unsigned number, and turning it negative, not writing a negative number.

This appears to apply to integers; floating-point numbers have a different syntax.

ashwin bhawsar
Ranch Hand
Posts: 62
Thanks for the replies.

Now i got that integers work on 2's compliment, the value swings between -ve and +ve values between a fixed range.
And if i am not wrong this works only for signed literals, but what about Unsigned types like floats. How things works there

I tried out this :

float f=2147483648;// obviously this won't work because floats as ints are 32-bit and so max it will hold 2147483647 value.

float f=2147483647;
f=f+1;
System.out.print(f); // the output is 2.14748365E9

What kind of binary arithmetic happened here , and how come float was able to hold "2.14748365E9" which is a double without an explicit cast.

Campbell Ritchie
Sheriff
Posts: 50208
79
No, it isn't a double. It is still a float. What actually happens in that the int undergoes an automatic widening conversion because it is assigned to a float. Because your int has ten digits in, and a float is only precise to 24 bits × log102 (= approx 7.2) digits, the last digits will be innacurate. You can keep adding 1 to (float)2147483647 and you should not notice any difference in the output, because the change is less than the precision of the float type.

Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15483
43
Floating-point types are not stored in two's complement, but in IEEE 754 format.
A float is in the 32-bit single precision format and a double is in the 64-bit double precision format.

ashwin bhawsar
Ranch Hand
Posts: 62

float f=2147483647+1;
System.out.print(f); // output is -2.14748365E9

OK , so here may be because (2147483647+1) results into an int (which is 32-bit ) and int is then assigned to ' f ' , and because ints are signed we are getting -ve value on overflow.

float f=(float)(2147483647+1); // explicit typecast
System.out.print(f);// output is still -2.14748365E9

How-come even after explicit typecast to float, ' f ' is getting a -ve value. Floats are originally unsigned.

The same thing occurs for doubles.

Matthew Brown
Bartender
Posts: 4568
9
In both cases you're still carrying out an integer operation, and then converting to a float. Try forcing a floating point operation by doing 2147483647+1F.

Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15483
43

float f=(float)(2147483647+1); // explicit typecast
System.out.print(f);// output is still -2.14748365E9

How-come even after explicit typecast to float, ' f ' is getting a -ve value. Floats are originally unsigned.

Because you put the (2147483647+1) between parentheses, which means that first the integers are added together and then the result is converted to a float - exactly the same as your first example. Try this instead:

Rob Spoor
Sheriff
Posts: 20665
65
Campbell Ritchie wrote:and a float is only precise to 24 bits × log102 (= approx 7.2) digits, the last digits will be innacurate.

Something that is made very clear with the following example:
Mathematically, these values are all different. In Java though, because of the inaccuracy, they are all equal. Change the 1 into something that falls within the accuracy (like 1000) and you will get three different values.

ashwin bhawsar
Ranch Hand
Posts: 62

Thanks a lot for your replies, they cleared a lot of my doubts.
Have found the memory representation for float.

Campbell Ritchie
Sheriff
Posts: 50208
79
The floating-point format is much more complicated than the diagram would make it appear, I am afraid.