Can anyone explain why the first if statement doesn't trigger true in the following code? If the equal to statement triggers true, why wouldn't the greater then or equal to? I can't figure it out. <?php $amount = 76.35; $amount = $amount - floor($amount); echo 'The calculated amount is ' . $amount . PHP_EOL; if ($amount >= 0.35) { echo 'It is great then or equal to 0.35' . PHP_EOL; } if ($amount = 0.35) { echo 'It is equal to 0.35' . PHP_EOL; } ?> Code (markup): Output: >php floor_test.php The calculated amount is 0.35 It is equal to 0.35 Code (markup): Thank you in advance.
All is documented here. -> http://php.net/manual/en/language.operators.comparison.php The second should be ==
Ok. Right, I overlooked that. So now both of them do not trigger. If the calculated amount is 0.35, then why wouldn't either one trigger true? <?php $amount = 76.35; $amount = $amount - floor($amount); echo 'The calculated amount is ' . $amount . PHP_EOL; if ($amount >= 0.35) { echo 'It is great then or equal to 0.35' . PHP_EOL; } if ($amount == 0.35) { echo 'It is equal to 0.35' . PHP_EOL; } ?> Code (markup):
I'm getting the value 0.34999999999999 .. As I'm sure you are getting .. That is definitely WEIRD .. Why PHP is deciding 76.35 - 76 is "0.34999999999999" is beyond me. Try round() or casting to int. But that should give you a clue as why it doesn't work!
0.35 is non terminating in binary the same way 1/3 is in decimal. This makes it actually NOT save 0.35. This is a common problem with using == on floting points or doubles. It is stored in a floting point btw because with a double it would end up as 0.35
I'm actually very interested in this. I understand what you're saying, but in 6+ yrs of PHP development I've never seen this before (and never had it cause a problem). What's the workaround? bcmath?
I am surprized you have never seen it before. There are 2 work arounds: 1) add a function for == for example function eql($x, $y, $epsilon){ return ($x < $y + $epsilon && $x > $y - $epsilon) } use a small epsilon depending on what your numbers are (so if you are using tenths make it 0.00001) 2) (not as good or proper) make them whole numbers then convert back later
$amount = 76.35; $result = number_format(($amount - floor($amount)), 2); if ($result > 0.35) { echo "Value ( $result ) is greater than 0.35. <br />"; } if ($result == 0.35) { echo "Value ( $result ) is equal to 0.35. <br />"; } PHP: Why couldn't you just format it ?
numberformat adds , for the thousands. It does not save the number differently (if it does then it makes it a string with the ,s). .03444444444... is what the comp sees. In this case if you forced it to a double it may end up rounding to be right but, that is still bad practice because it may not and it won't work for all numbers.
Result: 0.34999999999999431566 Compare with: 0.34999999999999997780 Code (markup): Sure it does have some cons but hey .. it does what it's supposed to do unless you want it to use for something it's haven't been built for. As long as the OP doesn't need anything specific, why not ?