Md. Mohd

Greenhorn

Posts: 12

posted 9 years ago

Hi All,

There are two examples related float precision. The only difference is the value of int i differs and both the example gives different results.

Please explain why?

Example 1:

int i = 1234567890;

float f = i;

int x = (int)f;

System.out.println(i == x); //Prints false

Example 2:

int i = Integer.MAX_VALUE;

float f = i;

int x = (int)f;

System.out.println(i == x); //Prints true

There are two examples related float precision. The only difference is the value of int i differs and both the example gives different results.

Please explain why?

Example 1:

int i = 1234567890;

float f = i;

int x = (int)f;

System.out.println(i == x); //Prints false

Example 2:

int i = Integer.MAX_VALUE;

float f = i;

int x = (int)f;

System.out.println(i == x); //Prints true

Anders Hermansen

Greenhorn

Posts: 6

posted 9 years ago

I would suggest that since Integer.MAX_VALUE is a constant (= will not change), the bit pattern stays the same and = = looks at the bit pattern.

Hence ex. 2 returns true.

Hence ex. 2 returns true.

Mohit Jain

Ranch Hand

Posts: 74

Kelvin Chenhao Lim

Ranch Hand

Posts: 513

posted 9 years ago

You'll have to know something about IEEE 754 floating-point encoding to really understand this issue completely.

But briefly, the most important point here is that a float value cannot represent every int value precisely. floats are 32 bits long, and ints are also 32 bits long--but some of the 32 bits in the float are used to store the exponent (i.e. the "power"), leaving the float with only 23 bits to store the number's actual significant digits (called the

The two numbers you used in your tests (1234567890 and Integer.MAX_VALUE) are examples of such large numbers. As a result, when you cast them to a float, the JVM will choose the

For 1234567890, the closest float value is 1234567936. Other int values "close" to 1234567890 will also be mapped to a float value of 1234567936. (To be precise, all ints from 1234567872 to 1234568000 will be mapped to this value.) This loss of precision causes the non-equality you observed when you cast the float back to an int.

Integer.MAX_VALUE (2147483647) is a more interesting case. This will get mapped to a float value of 2^31, or 2147483648. (All numbers from 2147483584 to 2147483776 will be mapped to this value.) However, when you cast this float value back to an int, this is larger than the maximum value of an int, so the JVM maps it back to Integer.MAX_VALUE. Hence your equality test prints "true".

Note that your code will print "true" for int values that are exactly representable with a float. As already mentioned, 1234567936 is one such number. The next smaller one is 1234567808, and the next larger one is 1234568064.

Also, you won't get any loss of precision converting an int to a double, because a double uses 52 bits for its significand. However, you'll run into the same problem if you convert a long to a double.

[ November 15, 2007: Message edited by: Kelvin Lim ]

But briefly, the most important point here is that a float value cannot represent every int value precisely. floats are 32 bits long, and ints are also 32 bits long--but some of the 32 bits in the float are used to store the exponent (i.e. the "power"), leaving the float with only 23 bits to store the number's actual significant digits (called the

**significand**). One more significant digit will automatically be assumed for most numbers (see the IEEE 754 spec). Therefore, once your int value is large enough that it requires more than 24 significant binary digits to represent, you're very likely to lose precision.The two numbers you used in your tests (1234567890 and Integer.MAX_VALUE) are examples of such large numbers. As a result, when you cast them to a float, the JVM will choose the

**closest**representable float value to your int value.For 1234567890, the closest float value is 1234567936. Other int values "close" to 1234567890 will also be mapped to a float value of 1234567936. (To be precise, all ints from 1234567872 to 1234568000 will be mapped to this value.) This loss of precision causes the non-equality you observed when you cast the float back to an int.

Integer.MAX_VALUE (2147483647) is a more interesting case. This will get mapped to a float value of 2^31, or 2147483648. (All numbers from 2147483584 to 2147483776 will be mapped to this value.) However, when you cast this float value back to an int, this is larger than the maximum value of an int, so the JVM maps it back to Integer.MAX_VALUE. Hence your equality test prints "true".

Note that your code will print "true" for int values that are exactly representable with a float. As already mentioned, 1234567936 is one such number. The next smaller one is 1234567808, and the next larger one is 1234568064.

Also, you won't get any loss of precision converting an int to a double, because a double uses 52 bits for its significand. However, you'll run into the same problem if you convert a long to a double.

**Edit: I should also note that none of this stuff is on the SCJP exam, so don't worry about it. But some of you may find this stuff interesting.**[ November 15, 2007: Message edited by: Kelvin Lim ]

SCJP 5.0

Mohit Jain

Ranch Hand

Posts: 74

posted 9 years ago

Kelvin Thanks a lot for such a nice description. By the way SCJP is an important step towards success in Java but its not the final destination. I really want to learn all this stuff well.

Please tell me what approach you have followed to learn all this stuff and how can I get to it apart from SCJP.

Please tell me what approach you have followed to learn all this stuff and how can I get to it apart from SCJP.

SCJP 5.0, SCWCD in progress

Dara Sitaramayya

Greenhorn

Posts: 3

posted 9 years ago

1 public class FloatTest {

2public static void main(String[] args) {

3int i = 1234567890;

4

5float f = i;

6

7int x = (int)f;

8

9System.out.println(i == x); //false

10System.out.println("i........."+i+";x........"+x);

11}

12

13 }

x and f are not same. o/p of 10th line :i.........1234567890; x........1234567936

2public static void main(String[] args) {

3int i = 1234567890;

4

5float f = i;

6

7int x = (int)f;

8

9System.out.println(i == x); //false

10System.out.println("i........."+i+";x........"+x);

11}

12

13 }

x and f are not same. o/p of 10th line :i.........1234567890; x........1234567936

It is sorta covered in the JavaRanch Style Guide. |