I can think of three different ways of looking at what a float
represents.
- You can say that a
float
is an exact value, which is the number that the 0's and 1's that make up thefloat
represent in binary. Afloat
is made up of a mantissa, an exponent and a sign bit, and you can do the mathematics to turn those 0's and 1's into an actual number. This is the most common way of looking at afloat
, and most people would consider it the most correct way. - You can think of a
float
as representing a range of values - basically all the numbers that closer to thatfloat
than to any other. This is useful when you've used afloat
for measuring something. - You can think of a
float
as representing the particular number within that range, which has the shortest decimal expansion. This idea is fraught with problems, but it has influenced the way Java works with floating point.
So consider the number x = 23.450000762939453125
. This number happens to be represented exactly by a float
, which I'll call f - that is, break f into its mantissa and exponent, do the calculation, and x
will come out.
The next number below x
that has can be represented exactly by a float is x - h = 23.4499988555908203125
. And the next number above x
that can be represented exactly by a float is x + h = 23.4500026702880859375
. I've just used h
to denote the gap between consecutive float
numbers around this magnitude.
Now, if you have any number in the range x - h / 2 = 23.44999980926513671875
up to x + h / 2 = 23.45000171661376953125
, then the closest float
to your number will be f. So that is the range of numbers that are represented by f - and of course, x
is right in the middle of this range.
You'll notice that 23.45
is in that range, and so is 23.450001
. What that means is that if you take the Java float
literal 23.45F
, its value is in fact f. The same is true of the Java float
literal 23.450001F
. And that's why the expression (23.45F == 23.450001F)
works out to be true
.
Now, when we try to print this float
number f, things start to get different between C++ and Java.
- In C++, the default way of printing a
float
is to find the number that it represents exactly, and round it to six decimal places. So what you get isx
rounded to six decimal places, which of course is23.450001
. - In Java, the default way of printing a
float
is to find the number within the represented range, with the shortest decimal expansion. In other words, Java will look for the number betweenx - h / 2
andx + h / 2
that it can write with the smallest number of decimal places. This number is23.45
.
So any C++ program will show f as 23.450001
, unless you specifically instruct the program to show it differently. Any Java program will show f as 23.45
, unless you specifically instruct the program to show it differently. But it's all the same float
.