3

For the purpose of the example, var 2 is preset from a database as "147.22" type STRING. var 1 is calculated previously in the script and has 147.22 type FLOAT.

Script:

<?

$var1 = (float)$var1;
$var2 = (float)$var2;

var_dump($var1);
var_dump($var2);

if($var1 < $var2) { echo "hello"; }

?>

My expected results would be that the script NOT echo "hello" since the two values are equal in amount and type.

However here is the output I'm getting:

float(197.22)
float(197.22)
hello

If I do not mess with the types and leave the one a float and the other a string, then it still does not work (this is how I got here in the first place).

If i force the values at the time of execution like this:

$var1 = 147.22;
$var2 = 147.22;

var_dump($var1);
var_dump($var2);

if($var1 < $var2) { echo "hello"; }

?>

I get this, (and it works):

float(197.22)
float(197.22)

Notice no "hello"....

Anyone have any clue wth is going on here?

Rick Kukiela
  • 1,052
  • 1
  • 13
  • 34

2 Answers2

8

If one of the floats is calculated numerically, and one is created from string assignment, they could be different. Try the following:

$x = 147.22;
$y = 147.2200000000001;
printf("%.40f\n", $x);
printf("%.40f\n", $y);
var_dump($x);
var_dump($y);
var_dump($x < $y);

outputs

147.2199999999999988631316227838397026062012
147.2200000000001125499693443998694419860840
float(147.22)
float(147.22)
bool(true)

Cast them to a string with a specified precision for comparison.

regality
  • 6,428
  • 6
  • 28
  • 26
  • Technically this was the correct answer (and posted first) so I'm giving credit here. Though credit and thanks to Nicholas is also due. "Cast them to a string with a specified precision for comparison." I ended up running them through number_format (which does excactly this) And it fixed the problem. I just find it odd that In 10 years of programming in php i've never came upon this issue before. The Float val is only adding two numbers that started as strings so I dont know why or how the precision of the decimal was effected. Meh. I'm gonna read the links Nicholas posted. – Rick Kukiela Nov 05 '11 at 07:48
2

If you are dealing with floats, then it's not safe to compare them directly, because there may be rounding or representation issues.

You'd better to check if the difference between those numbers is less than some predefined and very minimal epsilon, and then determine if they're equal, or which is the greater one.

This discussion may be worth reading: Is casting to float destructive?


EDIT:

More discussions to read:

Community
  • 1
  • 1
Nicolás Ozimica
  • 9,062
  • 5
  • 36
  • 49