The following code uses the values of type float
and double
respectively.
float a=99999.99F;
double b=a;
System.out.println("a : "+a);
System.out.println("b : "+b);
System.out.println("a==b : "+(a==b));
It displays the following output:
a : 99999.99
b : 99999.9921875
a==b : true
After execution, the values of a
and b
are 99999.99
and 99999.9921875
respectively though a==b
returns true
.
How does the comparison expression a==b
return true
?
Yes, instead of using equality operator (==), you can use relational operator e.g. less than (<) or greater than (>) to compare float and double values.
Double is more precise than float and can store 64 bits, double of the number of bits float can store. Double is more precise and for storing large numbers, we prefer double over float. For example, to store the annual salary of the CEO of a company, double will be a more accurate choice.
Performance-wise there's not likely to be much difference, and double may actually be faster. If Java is being run on a processor that doesn't have a floating-point unit at all, or supports 32-bit floats but not 64-bit floats, then a float could be faster.
In the case of floating-point numbers, the relational operator (==) does not produce correct output, this is due to the internal precision errors in rounding up floating-point numbers. In the above example, we can see the inaccuracy in comparing two floating-point numbers using “==” operator.
On the final line, where you compare a==b
, the value of a
is being implicitly promoted to double before the comparison. So, in effect, what is really being evaluated is (((double)a)==b)
which, of course, evaluates true, since b
was initialized by casting a
as double in the first place.
In other words, the last boolean expression (a==b)
asks:
is (some float value converted to a double)==(the same float value converted to a double somewhere else)
and the answer is : yes.
UPDATE: a commenter below made a good point: when a
is promoted to double, the stored numeric value does not actually change, even though it appears to because a different value is printed. The issue is with how floating point numbers are stored; without making this answer WAAAY too long and wading in past my depth, what you need to know is that some simple decimal values cannot be perfectly represented in binary floating point form, no matter how many digits you have (just like you can't perfectly represent 1/3
in base 10 without an infinite number of 3s, as in 0.333333...), so when you assign one of these values using float (a 32-bit representation of a floating point number) and then you convert it to a double (a 64-bit representation) and then use println
to display the value of that number, you may see more digits.
The println
method displays the shortest string of decimal digits that convert to the same float (or double) value the computer sees internally. Although the same numerical value is passed as argument in the first two calls to println
in your example, the double
type has more precision so println
needs to print more digits to show “the shortest string of decimal digits that would convert to (double)99999.99F
”. If your example had been 9999.50, both numbers would have printed the same, because binary numbers can represent 1/2
just fine.
NOTE: I am not even close to an expert on floating point numbers; you should check out (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) if you want a deeper understanding of what is going on here.
It is because in
double b = a;
the float value is converted (widened) to a double, but in
b == a
the same float value in a is again converted to a double to compare it with b. So, the outcome of the 2 conversions is the same.
The reason that printing a
and b
with:
System.out.println("a : "+a);
System.out.println("b : "+b);
shows different results is because the default floating-point printing for Java shows just enough digits to distinguish the number in its type. In float a=99999.99F;
, the value 99999.99 is not exactly representable in float
, so it is converted to the nearest representable value (99999.9921875), and a
is set to this value.
When a
is printed, “99999.99” is all that is needed to show the value.
Then double b=a;
sets b
to exactly the same value. However, since b
is double, there are other representable values in double
that are closer to 99999.99. If you had used double b = 99999.99;
, the fact that double
has more precision means b
would have been set to a value closer to 99999.99 (99999.990000000005238689482212066650390625). However, your code has set b
to a value farther from 99999.99 than that. So, when b
is printed, Java must use more digits to show that its value is not the double
that is closest to 99999.99.
Finally, when you compare a
and b
, the comparison returns true because a
and b
have exactly the same value.
In summary: a
and b
are exactly equal, but b
is printed with more digits because it is represented more finely in double
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With