Reputation: 27899
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
?
Upvotes: 5
Views: 1201
Reputation: 81105
It might be easier to see what's going on if one uses a different value. If, for example, one uses the value 1234512.345f, that value will print as 1234512.4, but if converted to double
it will print as 1234512.375
. The closest float
value to 1234512.345 is precisely equal to 1234512.375; the values on either side are 1234512.25 and 1234512.5; since the value 1234512.4 is closer to 1234512.375 than to either of those, there's no need to use more digits to represent something more precisely. There are many millions of double values between 1234512.375 and 1234512.4; thus, the shorter representation is not adequate for the purposes of showing that quantity as a double
. Java will thus use as many digits are are necessary to uniquely identify the value as a double
.
Upvotes: 1
Reputation: 2122
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.
Upvotes: 7
Reputation: 222352
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
.
Upvotes: 3
Reputation: 36329
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.
Upvotes: 4