Reputation: 45
And when I was reading the chapter about float points in C++ Primier Plus.
It gave an example as shown below:
#include <iostream>
int main(){
using namespace std;
float a = 2.34E+22f;
float b = a + 1.0f;
cout << "a =" << a <<endl;
cout << "b -a =" << b - a<< endl;
return 0;
}
And its result is:
a = 2.34e+22
b -a = 0
The explanation from the book is and I quote:
"The problem is that 2.34E+22 represents a number with 23 digits to the left of the decimal. By adding 1, you are attempting to add 1 to the 23rd digit in that number. But type float can represent only the first 6 or 7 digits in a number, so trying to change the 23rd digit has no effect on the value."
But I do not understand it. Could anybody help me to understand why b -a is 0 in a understandable way please?
Upvotes: 1
Views: 200
Reputation: 10323
The float
type in C/C++ is stored in the standard 'single precision' format. The numbers are of the form
±m*2^e
where m
is an integer between 223 and 224, and e
is an integer. (I'm leaving out a lot of details that are not relevant here.)
So how does this explain what you are seeing?
First of all, the numbers in your code are always "rounded" to the nearest floating-point number. So the value 2.34e+22
is actually rounded to 10391687*251, which is 23399998850475413733376. This is the value of a
.
Second, the result of a floating-point operation is always rounded to the nearest floating-point number. So, if you add 1 to a
, the result is 23399998850475413733377, which is again rounded to the nearest floating-point number, which is still, of course, 23399998850475413733376. So b
gets the same value as a
. Since both numbers are equal, a - b == 0
.
You can add numbers that are much larger than 1 to a
and still get the same result. The reason is again the fact that the result is rounded, and the closest floating-point number will still be a
when you add numbers up to at least 250, or about 1e+15.
Upvotes: 2
Reputation: 122493
The single precision floating point type float
is like this(assuming IEEE-754)
The fraction part has only 23 bits, roughly less than 107. When you add a rather small number to 2.34E+22f
, the precision of float
limits the result's representaion, so b
end up with unchanged value from a
.
Upvotes: 0
Reputation: 16320
Both the existing answers are correct (from Mark Ransom and Yu Hao).
The very short explanation is that float values are not very precise. The values are rounded off after 6 or 7 decimal digits. For very large numbers, this imprecision means that small changes to the value get rounded away to nothing. Even + 1
or + 100
can be a "very small change" if it's being done to 1000000000
.
Upvotes: 0
Reputation: 308530
b - a
is 0
because b
and a
are equal.
When you add a too small number to a large number, it's as if you didn't add anything at all.
In this case, "too small" would be anything less than about 2.34e+15 i.e. 7 digits smaller.
Upvotes: 1