php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login go to bug id or search bugs for
Bug #61108 Submitted: string math with vast differential numbers yield invalid math. 2012-02-16 17:18 UTC 2012-02-16 18:18 UTC qphoria at gmail dot com Not a bug Math related 5.3.10 Windows/Linux No None
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !

[2012-02-16 17:18 UTC] qphoria at gmail dot com
```Description:
------------
Tried this on the latest 5.3.10 and also on 5.2.17
It is a bit difficult to put into words, but math with varying string-number
sizes calculates wrong.

Simply put:

THIS IS CORRECT:
-----------------
\$x = 20.22
: double = 20.22
\$y = ("10.10" + "10.12");
: double = 20.22
\$x == \$y
: bool = TRUE

THIS IS BUGGED:
-------------------
\$x = 20.22
: double = 20.22
\$y = ("19.10" + "1.12"); //20.22
: double = 20.22
\$x == \$y
: bool = FALSE

For some reason, if you have a wide number spread in the string math, the
boolean fails, even though they are both shown as float/double numbers

The simple fix is to wrap round() around the string math. Can't really explain
it.

Test script:
---------------
<?php
\$x = 23.36;
\$y = ("21.42" + "1.94");
if (\$x < \$y) {
echo "math fail<br/>";
} else {
echo "math win<br/>";
}
var_dump(\$x, \$y);
echo "<br/>";

\$x = 23.36;
\$y = ("10.36" + "13.00");
if (\$x < \$y) {
echo "math fail<br/>";
} else {
echo "math win<br/>";
}
var_dump(\$x, \$y);
?>

Expected result:
----------------
I expect to see:

math win
float(23.36) float(23.36)
math win
float(23.36) float(23.36)

Actual result:
--------------
What I really see is:

math fail
float(23.36) float(23.36)
math win
float(23.36) float(23.36)

```

## History

[2012-02-16 17:24 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
[2012-02-16 17:24 UTC] rasmus@php.net
```Floating point values have a limited precision. Hence a value might
not have the same string representation after any processing. That also
includes writing a floating point value in your script and directly
printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE
http://www.floating-point-gui.de/

Thank you for your interest in PHP.

.
```
[2012-02-16 17:50 UTC] qphoria at gmail dot com
```Perhaps, but then why wouldn't the additional decimals show in the variable?
The initial string math should have returned:
20.22000003
if that was the case.

I would expect to see:

\$x = 20.22
: double = 20.22
\$y = ("10.10" + "10.12");
: double = 20.22000030
or
20.22e08 or something
```
[2012-02-16 18:00 UTC] qphoria at gmail dot com
```It seems the proposed solution is that we should always add
round(\$y,2)
to any string math. But if php is going to return exact numbers to the variable
dump, but hide the "real" value in the back end.. then what is the point? The
bug may not be with floating, but instead with the way php outputs the variable.
If we are meant to always round string math, then you may as well add the
round() function to the last step of the string math result in the php exe and
spare the rest of us. Nobody can trust (float) now because what php outputs
isn't really what it uses to calculate. Unless there is some way to find out
that hidden "epsilon" value.
```
[2012-02-16 18:05 UTC] qphoria at gmail dot com
```I guess this would be a more relevant read:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

Seems to clear it up more.
```
[2012-02-16 18:18 UTC] rasmus@php.net
```If you change your output precision setting you will see it. But that is just for
final output purposes. If we rounded every float internally you would lose a lot
of precision since all these would pile up and cause actual math errors. But yes,
it does mean you have to be careful if you are trying to do strict equivalence
checking on floats. But that is the same for most languages that use the
underlying float implementation. There are higher-level ones, of course, but they
are quite a bit slower.
```