Hi folks. I have a strange thing happening here. I have a loop where counter gets incrememnted by 0.1 starting from 0 and up to 1. In each iterration I use the counter in an expression with modulo operator. I get incorrect result when the counter has values of 0.8 and 1. This is the code:

<?php
echo '<pre>';
for($i = 0; $i <= 1; $i += 0.1) {
    // result of an expression
    $result = ($i * 10) % 10;
    // display $i, the expression and the result of the expression
    // when $i equals 0.8 and 1 the result is incorrect!!!
    echo "i: $i  =>>  ($i * 10) % 10 = $result <br />";
}
echo '<pre>';
?>

and here is the output I get:

i: 0  =>>  (0 * 10) % 10 = 0 
i: 0.1  =>>  (0.1 * 10) % 10 = 1 
i: 0.2  =>>  (0.2 * 10) % 10 = 2 
i: 0.3  =>>  (0.3 * 10) % 10 = 3 
i: 0.4  =>>  (0.4 * 10) % 10 = 4 
i: 0.5  =>>  (0.5 * 10) % 10 = 5 
i: 0.6  =>>  (0.6 * 10) % 10 = 6 
i: 0.7  =>>  (0.7 * 10) % 10 = 7 
i: 0.8  =>>  (0.8 * 10) % 10 = 7 <-- this is incorrect
i: 0.9  =>>  (0.9 * 10) % 10 = 9 
i: 1  =>>  (1 * 10) % 10 = 9     <-- this is incorrect

Can anybody test this code and see if the result is the same. Any ideas why this?

commented: Thanks for this +14

You can't print it like that.

What is the correct way of printing it?

Sorry I am wrong...

PHP Bug?

The error appears to happen even when casting to integer:

for($i = 0; $i <= 1; $i += 0.1) {

    $cast_to_int = (int) ($i * 10);

    // result of an expression
    $result = $cast_to_int % 10;

    // display $i, the expression and the result of the expression
    echo "i: $i  =>> $cast_to_int % 10 = $result <br />";
}

Seems like one has to be careful when using floats in some exressions.

@iamthwee: thanks for the link.

I will leave this thread open for a couple of days so other can comment then I will mark it as solved.

Member Avatar

diafol

very odd. It seems that this casting (or not as the case may be) uses was appears to be floor(). Using ceil() for the cast, gives problems with 0.3 (=4). Manually setting (0.8*10)%10 works fine.

Member Avatar

diafol

OK, that was mad. I got around the problem with casting the initial calculation to string and then casting the second as integer:

for($i=0;$i<=1;$i+=0.1) {
    $str_cast = (string)($i * 10);
    $result = (int)($str_cast) % 10;
    echo "i: $i  =>> $str_cast % 10 = $result <br />";
}

Thanks for flagging up that problem - will keep a lookout for than in future projects +1

Or for a single liner:

for($i=0;$i<=1;$i+=0.1) {
    echo (int)(string)($i * 10) % 10;
}
commented: great! +9

I got around the problem with casting the initial calculation to string and then casting the second as integer

Thnx diafol, that works, I'll actually use your hack :-).

In noticed some similar behaviour with fmod() but just have no time to play arround with it just now.

Member Avatar

diafol

OK, great. Solved?