3

I am working on a project for a client, its a quite simple. But there is one calculation I have to make which is also very simple, its like this example:

$a = (49.95 - 24.95);
if ($a == 25.00) {
    echo "TRUE";
} 

This equals 25.00 right! But no its returning false???

But if I do this, another example similar to a calculation I need:

$a = (99.95 - 24.95);
if ($a == 75.00) {
    echo "TRUE";
}

Then I get true! Am I going mad, or is this a bug???

4 Answers4

2

Like you can read in manual, don't compare float directly. Instead use epsilon.

<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if(abs($a-$b) < $epsilon) {
    echo "true";
}

That's because of the way how PHP stores float internally. You can read about it in manual, eg. here http://pl1.php.net/float

Elon Than
  • 9,603
  • 4
  • 27
  • 37
2

It's not a bug. It's about float number precision. Since float numbers are stored with decimal precision, you can't rely on precise compare operations, like == (equality comparison).

Instead you shoult use precision delta and compare floats like:

$a = (49.95 - 24.95);
$b = 25;
$delta = 1E-13;

if(abs($a-$b)<$delta)
{
   echo('TRUE');
}

In PHP, 1E-13 will be enough for using as precision delta. For very simple explanation, see this guide about float numbers and their representation.

Alma Do
  • 37,009
  • 9
  • 76
  • 105
  • Thank you, that works perfectly, I just could not get me head arround why the first example was not working and the second was. – user2863313 Oct 10 '13 at 12:35
1
$a = (49.95 - 24.95);
if ((int)$a == 25) {
    echo "TRUE";
}
Nanhe Kumar
  • 15,498
  • 5
  • 79
  • 71
0

At the first example there is a float number which is compared to an int number and at the second there is a float number compared to a float number. The difference occurs because of the floating point precision and its not a bug.

To solve this you can define a d (delta) number which will be the precision of the calculation

and then you could check if the absolute result of x-y will be lower then the precision you defined. Something like this if(abs(x-y) < d)

MaD
  • 780
  • 7
  • 19