1

I have a problem with PHP comparing after I divide a value float and integer.

Here my code :

<?php

    function test_promo($price) {
        $tmpprice = $price*100;
        $divprice = $tmpprice/intval($tmpprice);
        if ( $divprice > 1 ) {
            echo "$price = TRUE\n";
            //TODO do something >1
        }
        else {
            echo "$price = FALSE\n";
            //TODO do something <=1
        }
    }

    echo "<pre>";
    test_promo(2.41);   //output--> 2.41 = FALSE
    test_promo(2.42);   //output--> 2.42 = FALSE
    test_promo(2.43);   //output--> 2.43 = TRUE
    test_promo(2.44);   //output--> 2.44 = FALSE
    test_promo(2.45);   //output--> 2.45 = TRUE
    test_promo(2.46);   //output--> 2.46 = FALSE
    test_promo(2.47);   //output--> 2.47 = TRUE
    test_promo(2.48);   //output--> 2.48 = FALSE
    test_promo(2.49);   //output--> 2.49 = TRUE
    echo "</pre>";

?>

As you can see the result must be all FALSE but it's not :S

Is it a bug in PHP or just only my computer (Ubuntu x64) has this bug?

SOLUTION :

As the corrected answer below, I need to get only float number as define (the number after .) like this $divprice = number_format( $newprice/intval($newprice), 2 );

Kannika
  • 2,538
  • 2
  • 27
  • 38
  • 2
    This is related to floating point manipulation. I see no reason to suspect all these values must be false. – JayC Feb 24 '13 at 05:00
  • No, I need the other float that existing to test. if I put value `test_promo(2.444)` I will lost a number `0.4`. – Kannika Feb 24 '13 at 05:21

3 Answers3

4

Floating points can not represent exactly the value you posted in decimal. In other words, 2.43 is not really 2.43, but actually [something close to] 2.4300000000000003. So when you divide 243.00000000000003 by 243 the result will be greater than 1.

This is not a bug in PHP, just the way floating point works (in any language). If you need to work with exact decimal values, you'd better search for a specific library to do that. This question might be a good starting point.

Community
  • 1
  • 1
mgibsonbr
  • 21,755
  • 7
  • 70
  • 112
2

You need to cast $divprice to integer because your $divprice is float now and because of this fact:

PHP.NET

testing floating point values for equality is problematic, due to the way that they are represented internally. However, there are ways to make comparisons of floating point values that work around these limitations.

Solution:

$divprice = (int) ($tmpprice/intval($tmpprice));
1

This is probably related to how floating point numbers are handled (in any language). You could call this round-off error or whatever but as a general rule it is not recommended to compare floating points for equality. So in this case using if($divprice==1) would also give unexpected results.

mtariq
  • 400
  • 1
  • 10