0

I would like to create a loop that keeps adding a set fraction, here in my example 1/3, and which later I can check against for matches with integer values.

Obviously when php adds 1/3 + 1/3 + 1/3 the result is 0.9999999, so i thought I could use the occasional round to help me, but this isn't working either.

The idea that I had would be that .333 + .333 becomes .666 and that if rounded that would become .667, then + .333 and the result is 1. However round only seems to work, for me, if the number of digits actually decreases. so round (0.666, 3) remains 0.666

<?php
    $denom = 3;
    $frac = 1/$denom;
    $frac = round($frac,3);

    $value = 0;
    $max =24;
    for($f = 1; $f <= $max; $f++){
    echo "old value is now at ".$value.".<br/>";
    $value = $value+$frac;
    echo "value is now at ".$value.".<br/>";
    $value = round($value,3);
    echo "rounded value is now at ".$value.".<br/>";
    $valueArray[$f] = $value;
    //and here for ease of testing....
    if (($value==1)OR ($value==2)OR ($value==3)OR ($value==4)OR ($value==5)OR ($value==6)OR ($value==7)OR ($value==8)){
         echo "match!<br/>";
    }else{
        echo "no match!<br/>";
    }
    }


?>

Am I going about this in a totally stupid way?

Accuracy when the value is not an integer is not needed, just that it can == with integers.

EnglishAdam
  • 1,380
  • 1
  • 19
  • 42

2 Answers2

0

I'm not sure why you are trying to round the values...

$i = 1/3;

echo $i . PHP_EOL;
echo 3*$i . PHP_EOL;
echo $i+$i+$i . PHP_EOL;

// prints:
// 0.33333333333333
// 1
// 1
tsdtsdtsd
  • 375
  • 4
  • 17
  • if you save $i as a variable it is not the same as 1/3, see the warning float precision in the manual, http://de3.php.net/manual/en/language.types.float.php#warn.float-precision – EnglishAdam Oct 21 '13 at 10:58
0

If you really want to handle rationals accurately (ones that cannot be represented in the limited precision IEEE754 data types), you should store them as rationals.

In other words, get yourself a class that can handle a type {numerator, denominator} (both integers) and performs the arithmetic you need on them.

That way, the value will stay accurate through to the end point, where you can either print out the rational as a rational or convert it to decimal with only one level of conversion "error" rather than many of them being accumulated.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953