PHP floor function on float value

Ever wondered why your calculations are wrong in PHP when dealing with floating numbers? Well, TechieDan had that problem while doing some calculation which involves using the floor() function in PHP (which was mentioned previously).

PHP Logo

Here is the scenario.

$test = floor(6.92 / 12 * 1000) / 1000 * 200000 / 1000;

echo $test;
// This prints the correct value 115.2 but... how about the below?

$test = floor($test * 100);

echo $test;
/*
 * The weird side of PHP!!!
 * This should print 11520 but
 * instead it printed out 11519.
 */

Why does this happen? To cut the long story short, this happens as floating values (in this instance $test) could be kept as numbers equivalent to 115.199999999999 for a value of 115.20. Thus after using floor for the value again, would yield a different result because it is now 11519.

Here’s the longer explanation regarding this behavior sourced from php.net.

Floating point numbers have limited precision. Although it depends on the system, PHP typically uses the IEEE 754 double precision format, which will give a maximum relative error due to rounding in the order of 1.11e-16. Non elementary arithmetic operations may give larger errors, and, of course, error propagation must be considered when several operations are compounded.

Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9999999999999991118….

So never trust floating number results to the last digit, and do not compare floating point numbers directly for equality. If higher precision is necessary, the arbitrary precision math functions and gmp functions are available.

Many PHP programmers would have faced this situation once at least in their programming life.

Solution

So how did this programmer in TechieDan solve this issue?

Use the strval() before doing a floor() function. Huh?

Observe

$test = floor(6.92 / 12 * 1000) / 1000 * 200000 / 1000;

echo $test;
// This prints the correct value 115.2 but... how about the below?

$test = floor(strval($test * 100));

echo $test;
/*
 * It now prints out 11520.
 */

VOILA!! Once again, the weird side of PHP and floating numbers solved once again. Do comment and subscribe to my feeds if you find this helpful so that I will know if this actually helped you.

One Response

  1. Pingback: PHP Round Up to Nearest 5 Cents | TechieDan January 15, 2014
  2. Chris July 19, 2016

Leave a Reply