I learned that 0.1 + 0.2 != 0.3
due to the 0.1 and 0.2 are both not accurately 0.1 and 0.2.
However, why the following Python code prints out "True"?
float1 = 1.0/100.0
float2 = 0.1/10.0
print( float1 == float2 )
Same applies to C:
double slope1 = 1.0 / 100.0;
double slope2 = 0.1 / 10.0;
int main(int argc, const char * argv[]) {
printf( "%d", slope1 == slope2 );
}
What did I miss or misunderstand? kindly teach.
I learned that 0.1 + 0.2 != 0.3
due to the 0.1 and 0.2 are both not accurately 0.1 and 0.2.
However, why the following Python code prints out "True"?
float1 = 1.0/100.0
float2 = 0.1/10.0
print( float1 == float2 )
Same applies to C:
double slope1 = 1.0 / 100.0;
double slope2 = 0.1 / 10.0;
int main(int argc, const char * argv[]) {
printf( "%d", slope1 == slope2 );
}
What did I miss or misunderstand? kindly teach.
Share Improve this question edited Feb 17 at 7:36 PkDrew asked Feb 16 at 16:22 PkDrewPkDrew 1,0216 silver badges22 bronze badges 11- 5 Not a dupe. The OP is well aware that FP math is "broken". In fact, the question is why isn't it broken in this case. – ikegami Commented Feb 16 at 16:47
- 3 You haven't shown any argument, why they shouldn't be. – gre_gor Commented Feb 16 at 16:55
- 1 The results are not mathematically equal, as you expected. But the difference is too small, so it is rounded to the same value. Try Decimal to visualize this. – ken Commented Feb 16 at 17:29
- 3 Why was this question closed? It's quite clear what OP is asking. I'm voting to reopen. – ad absurdum Commented Feb 17 at 0:06
- 2 @PkDrew,Title does not match posted code sample. Improve post by making them match. – chux Commented Feb 17 at 7:27
2 Answers
Reset to default 7It's just lucky. It isn't always. For example:
>>> 0.0001 / 100
1e-06
>>> 0.00001 / 10
1.0000000000000002e-06
Or two more similar cases, one lucky and one unlucky:
>>> 6.0 / 100
0.06
>>> 0.6 / 10
0.06
>>> 7.0 / 100
0.07
>>> 0.7 / 10
0.06999999999999999
One-hundredth is periodic in binary just like one-third is periodic in decimal.
____________________
1/100 = 0.0000001010001111010111
This means it can't be represented exactly as a floating point number. The closest you can get using IEEE double-precision:
$ perl -Mv5.14 -e'say sprintf( "%.1074f", $ARGV[0] ) =~ s/\.?0+\z//r' 0.01
0.01000000000000000020816681711721685132943093776702880859375
But none of that is relevant. No matter how precisely or inexactly one-hundredth is stored, you are comparing one-hundredth with one-hundredth. So it should be no surprise they are equal.
Now, you did obtain one-hundredth using two different approaches, so floating-point error could have slipped in causing the results to be different. But that did not happen.