Re: round()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/11/07, tedd <tedd@xxxxxxxxxxxx> wrote:
>
> At 4:18 PM -0600 10/10/07, <admin@xxxxxxxxxxxxxxxxxxx> wrote:
> >I disagree. I will need to see an example where the round() is
> inaccurate.
>
>
> You may disagree if you wish, but the php function round() is
> inaccurate by definition -- all *rounding* algorithms are inaccurate.
>

thats why i suggested the bcmath based algorithm, as bcmath supports
arbitrary
precision.  i built a quick test script using the method from the top
comment of the
bcmath page, and round().  it allows for quick comparisons of the 2
algorithms and
tells you if the results are the same.  i messed around w/ it a little bit
and the results
were the same every time.

nathan@devel ~/working/www $ vim bcRound.php
nathan@devel ~/working/www $ ./bcRound.php 5.58635634564356 6
round result: 5.586356
roundbc result: 5.586356
the results are different
nathan@devel ~/working/www $ vim bcRound.php
nathan@devel ~/working/www $ ./bcRound.php 5.58635634564356 6
round result: 5.586356
roundbc result: 5.586356
the results are the same
nathan@devel ~/working/www $ ./bcRound.php 5.58635634564356 8
round result: 5.58635635
roundbc result: 5.58635635
the results are the same
nathan@devel ~/working/www $ ./bcRound.php 5.58635634564356 3
round result: 5.586
roundbc result: 5.586
the results are the same


i dont know what the point of the toFixed() function is (posted earlier).
round takes a second parameter that specifies the desired precision.

#!/usr/bin/php
<?php
if($argc != 3) {
    die('Usage: rounder.php <float> <precision>' . PHP_EOL);
}

$float = $argv[1];
$precision = $argv[2];

$roundResult = round($float, $precision);
$roundbcResult = roundbc($float, $precision);

echo "round result: $roundResult" .  PHP_EOL;
echo "roundbc result: $roundbcResult" . PHP_EOL;

if($roundResult !== $roundbcResult) {
    echo 'the results are the same' . PHP_EOL;
} else {
    echo 'the results are different' . PHP_EOL;
}

    /// borrowed from post on php.net
    function roundbc($x, $p) {

        $x = trim($x);
        $data = explode(".",$x);

        if(substr($data[1],$p,1) >= "5") {

           //generate the add string.
           $i=0;
           $addString = "5";
            while($i < $p) {
                $addString = "0" . $addString;
                $i++;
            }//end while.

           $addString = "." . $addString;

           //now add the addString to the original fraction.
           $sum = bcadd($data[0] . "." . $data   [1],$addString,$p+1);

           //explode the result.
           $sumData = explode(".",$sum);

           //now, return the correct precision on the rounded number.
           return $sumData[0] . "." . substr($sumData[1],0,$p);

         } else {
           //don't round the value and return the orignal to the desired
           //precision or less.
           return $data[0] . "." . substr($data[1],0,$p);

      }//end if/else.

    }//end roundbc.
?>


-nathan

[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux