Possible Duplicate:
Strange addition of numeric strings in PHP
$r = 1.0 - 0.8 - 0.2;
var_dump($r);
I get float -5.5511151231258E-17. The same result i get in C++ and C#.
MySQL i get result 0.0 via query:
SELECT 1.0 - 0.8 - 0.2
Possible Duplicate:
Strange addition of numeric strings in PHP
$r = 1.0 - 0.8 - 0.2;
var_dump($r);
I get float -5.5511151231258E-17. The same result i get in C++ and C#.
MySQL i get result 0.0 via query:
SELECT 1.0 - 0.8 - 0.2
Let it be clear: 0.8
has finite representation in decimal because it has value 8/10¹
.
But in base 2, it has value: 1/2 + 1/4 + 0/8 + 0/16 + 1/32 + 1/64 + 0/128 + ... and it has no end, like one third has no end in decimal representation (0.333…
) but would be 0.1
in base 3.
0.8 = 0.110011001100110011001100... in binary
0.2 = 0.001100110011001100110011... in binary
Your computer stores floating point values in binary representation. So, there is a loss of precision when you add, subtract, multiply, etc. numbers.
C++, C and C# are compiled languages, and floats are stored on typically 4 or 8 bytes. You cannot store 0.8 in a float.
MySQL might tell you 0 because it truncates the results of the calculation.
If you want a library that performs calculations without losses of precision in any base, look up GMPlib.
You can avoid it by using BCMath (bcsub() for this case). Or you can simply round() (note that you can set the precision on 2nd argument). For all cases you will receive -0
, if you need positive 0
just use abs().
See what I talk about here.
Code example:
<?php
echo 'Direct: ' . ( 1.0 - 0.8 - 0.2 ) . '<br/>';
echo 'BC Math: ' . bcsub( bcsub('1.0', '0.8'), '0.2' ) . '<br/>';
echo 'Round: ' . round( 1.0 - 0.8 - 0.2 ) . '<br/>';
echo 'Absolute: ' . abs( round( 1.0 - 0.8 - 0.2 ) ) . '<br/>';
?>