3

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?

Votes + Comments
Thanks for this
6
Contributors
12
Replies
22
Views
5 Years
Discussion Span
Last Post by DarkMonarch
Featured Replies
  • 2

    Or maybe it is designed as intended due to floating point precision? https://bugs.php.net/bug.php?id=61580 Read More

  • 1
    cereal 1,515   5 Years Ago

    This happens also in javascript, I found this problem while working on a cart application. Check also these: http://stackoverflow.com/questions/3726721/php-math-precision & http://stackoverflow.com/questions/1458633/elegant-workaround-for-javascript-floating-point-number-problem Read More

  • 4
    diafol 3,720   5 Years Ago

    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 … Read More

0

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.

0

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.

Edited by diafol

4

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

Edited by diafol

Votes + Comments
great!
0

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.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.