Question about IF Greater Then or Equal To Inconsistency

Discussion in 'PHP' started by dsulli03, Apr 26, 2010.

  1. #1
    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.
     
    dsulli03, Apr 26, 2010 IP
  2. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #2
    danx10, Apr 26, 2010 IP
  3. dsulli03

    dsulli03 Peon

    Messages:
    2
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    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):
     
    dsulli03, Apr 26, 2010 IP
  4. nezZario

    nezZario Peon

    Messages:
    45
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    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!
     
    nezZario, Apr 26, 2010 IP
  5. nolag

    nolag Member

    Messages:
    201
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    28
    #5
    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
     
    nolag, Apr 26, 2010 IP
  6. nezZario

    nezZario Peon

    Messages:
    45
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #6
    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?
     
    nezZario, Apr 26, 2010 IP
  7. nolag

    nolag Member

    Messages:
    201
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    28
    #7
    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
     
    nolag, Apr 26, 2010 IP
  8. winecode

    winecode Guest

    Messages:
    5
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #8
    $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 ?
     
    winecode, Apr 26, 2010 IP
  9. nolag

    nolag Member

    Messages:
    201
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    28
    #9
    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.
     
    nolag, Apr 26, 2010 IP
  10. winecode

    winecode Guest

    Messages:
    5
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #10
    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 ? :)
     
    winecode, Apr 26, 2010 IP
  11. bytes

    bytes Peon

    Messages:
    39
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #11
    http://ua2.php.net/manual/en/language.types.float.php
     
    bytes, Apr 27, 2010 IP
  12. joebert

    joebert Well-Known Member

    Messages:
    2,150
    Likes Received:
    88
    Best Answers:
    0
    Trophy Points:
    145
    #12
    if ((string)$amount >= 0.35)
    PHP:
     
    joebert, Apr 28, 2010 IP