0

I was working on a code and I could not understand the weird result I was getting.

<?php

    $a = 0.01;  
    $p = pow(0.1, 2); // result: 0.01

    if( $a < $p ){
        echo "true";
    }

?>

The result of this condition is always "true" while both of the variables have same value, but the result coming from pow is changing something internally. Seems like I would not be able to rely on this function. Would someone please help me figuring this out ?

Darren
  • 13,050
  • 4
  • 41
  • 79
Arfeen
  • 2,553
  • 5
  • 29
  • 48

2 Answers2

2

its because of float inaccuracy, take a look at answered question mentioned in comment by b0s3

Read the red warning first http://www.php.net/manual/en/language.types.float.php. You must never compare floats for equality. You should use the epsilon technique.

For example:

if (abs($a-$b) < EPSILON) { … } where EPSILON is constant representing a very small number (you have to define it)

https://stackoverflow.com/a/3149007/4998045

so you can trust pow function but you cant trust float comparsion

Community
  • 1
  • 1
Pepo_rasta
  • 2,842
  • 12
  • 20
  • this looks good. In my case, it is working while having EPSILON value of 0.000000000000000001, if I decrease another zero, it won't give me correct result. – Arfeen Aug 10 '15 at 08:24
  • but watch out, with different operations with float comes different inaccuracy, so choose wisely your EPSILON value, because too small values should not work in other cases – Pepo_rasta Aug 10 '15 at 09:09
1

PHP Docs said:

base raised to the power of exp. If both arguments are non-negative integers and the result can be represented as an integer, the result will be returned with integer type, otherwise it will be returned as a float.

Maybe you need to convert all to int or all to float.

if( (float)$a < (float)$p ){
    echo "true";
}

See it run:

http://phpfiddle.org/main/code/2hv5-n2fw

Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
  • true, but this is not the problem here – Pepo_rasta Aug 10 '15 at 08:03
  • @Pepo_rasta that's the problem here. OP thinks that `pow` function is making internal changes, and it's true. The function returns the value with the type according to it. If you compare ints with floats, the problem is that OP said. – Marcos Pérez Gude Aug 10 '15 at 08:05
  • 1
    no, you have mistake in your fiddle dude, OP using `pow(0.1,2);` and you using `pow(0.01, 2);` which return 0.001, comparsion between int and float working slightly well... ps: how can you think, that 0.01 is returned as int? – Pepo_rasta Aug 10 '15 at 08:14
  • @MarcosPérezGude it doesn't work. – Arfeen Aug 10 '15 at 08:20