This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
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.
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.
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.
But what about this :
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.
Joined: Oct 13, 2005
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.
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:
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.