note 92920 added to function.bcscale

From: Date: Fri, 14 Aug 2009 19:36:42 +0000
Subject: note 92920 added to function.bcscale
Groups: php.notes 
Request: Send a blank email to php-notes+get-159490@lists.php.net to get a copy of this message
The function provided by "mwgamera at gmail dot com" (http://www.php.net/function.bcscale#79628) 2 comments below doesn't work well with negative numbers. Example: <?php bcscale(3); var_dump(round(-1, 2)); // float(-1) var_dump(bcround('-1', 2)); // string(5) "-0.99" => incorrect $a = bcdiv('-1', '3'); var_dump(round($a, 2)); // float(-0.33) var_dump(bcround($a, 2)); // string(5) "-0.32" => incorrect $a = bcdiv('-2', '3'); var_dump(round($a, 2)); // float(-0.67) var_dump(bcround($a, 2)); // string(5) "-0.66" => incorrect ?> Here is a modified version that works correctly: <?php /** * Round an arbitrary precision number * * @param string $sNumber The value to round. * @param int $iPrecision The optional number of decimal digits to round * to, defaults to 0. * @return string The rounded value. */ function bcround($sNumber, $iPrecision = 0) { $iPrecision = (int) $iPrecision; $sZeros = str_repeat('0', abs($iPrecision)); if (0 > $iPrecision) { return bcmul(bcround(bcdiv($sNumber, '1'.$sZeros, 1)), '1'.$sZeros, 0); } else { $sSign = ''; if ('-' === substr($sNumber, 0, 1)) { $sSign = '-'; } return bcadd($sNumber, $sSign.'0.'.$sZeros.'5', $iPrecision); } } ?> Example: <?php bcscale(3); var_dump(round(-1, 2)); // float(-1) var_dump(bcround('-1', 2)); // string(5) "-1.00" => correct $a = bcdiv('-1', '3'); var_dump(round($a, 2)); // float(-0.33) var_dump(bcround($a, 2)); // string(5) "-0.33" => correct $b = bcdiv('-2', '3'); var_dump(round($b, 2)); // float(-0.67) var_dump(bcround($b, 2)); // string(5) "-0.67" => correct ?> Like the round() function, it also accepts negative precision: <?php $a = '123456'; var_dump(round($a, -2)); // float(123500); var_dump(bcround($a, -2)); // string(6) "123500"; $a = '-123456'; var_dump(round($a, -2)); // float(-123500); var_dump(bcround($a, -2)); // string(6) "-123500"; ?> Bonus: below is a function that does what "Nitrogen" (http://www.php.net/function.bcscale#88463) did 1 comment below: <?php /** * Strip trailing zeros of an arbitrary precision number * * @param string $sNumber The value to trim. * @param string The modified value. */ function bctrim($sNumber) { $iPosition = strpos($sNumber, '.'); if (FALSE === $iPosition) { return $sNumber; } else { return substr($sNumber, 0, $iPosition). rtrim(substr($sNumber, $iPosition), '.0'); } } ?> Example: <?php var_dump(bctrim('1000')); // string() "1000" var_dump(bctrim('1000.0000')); // string() "1000" var_dump(bctrim('1000.1000')); // string() "1000.1" var_dump(bctrim('1000.0001')); // string() "1000.0001" ?> ---- Server IP: 69.147.83.197 Probable Submitter: 91.181.166.214 ---- Manual Page -- http://www.php.net/manual/en/function.bcscale.php Edit -- https://master.php.net/note/edit/92920 Del: integrated -- https://master.php.net/note/delete/92920/integrated Del: useless -- https://master.php.net/note/delete/92920/useless Del: bad code -- https://master.php.net/note/delete/92920/bad+code Del: spam -- https://master.php.net/note/delete/92920/spam Del: non-english -- https://master.php.net/note/delete/92920/non-english Del: in docs -- https://master.php.net/note/delete/92920/in+docs Del: other reasons-- https://master.php.net/note/delete/92920 Reject -- https://master.php.net/note/reject/92920 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#159490) next »