Kannika
Kannika

Reputation: 2558

PHP has a bug comparing after divide

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 );

Upvotes: 1

Views: 99

Answers (3)

mgibsonbr
mgibsonbr

Reputation: 22007

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.

Upvotes: 4

user1646111
user1646111

Reputation:

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));

Upvotes: 2

mtariq
mtariq

Reputation: 410

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.

Upvotes: 1

Related Questions