note 97722 deleted from function.bcadd by danbrown
| From: | danbrown@php.net | Date: | Wed, 05 May 2010 14:17:21 +0000 |
| Subject: | note 97722 deleted from function.bcadd by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-168969@lists.php.net to get a copy of this message | ||
Note Submitter: Gemorroj
----
the code was formated and the bug from the previous post was fixed: if variables $Num1 and $Num2 are
not float numerics and where variable $Scale = 0
<?php
class Math
{
static public function add ($num1, $num2, $scale = null)
{
// check if they're valid positive numbers, extract the whole numbers and decimals
if (!preg_match("/^\+?(\d+)(\.\d+)?$/", $num1, $tmp1) ||
!preg_match("/^\+?(\d+)(\.\d+)?$/", $num2, $tmp2)) {
return('0');
}
// this is where the result is stored
$output = array();
// remove ending zeroes from decimals and remove point
$dec1 = isset($tmp1[2]) ? rtrim(substr($tmp1[2], 1), '0') : '';
$dec2 = isset($tmp2[2]) ? rtrim(substr($tmp2[2], 1), '0') : '';
// calculate the longest length of decimals
$dLen = max(strlen($dec1), strlen($dec2));
// if $Scale is null, automatically set it to the amount of decimal places for accuracy
if ($scale === null) {
$scale = $dLen;
}
// remove leading zeroes and reverse the whole numbers, then append padded decimals on the
end
$num1 = strrev(ltrim($tmp1[1], '0') . str_pad($dec1, $dLen, '0'));
$num2 = strrev(ltrim($tmp2[1], '0') . str_pad($dec2, $dLen, '0'));
// calculate the longest length we need to process
$mLen = max(strlen($num1), strlen($num2));
// pad the two numbers so they are of equal length (both equal to $mLen)
$num1 = str_pad($num1, $mLen, '0');
$num2 = str_pad($num2, $mLen, '0');
// process each digit, keep the ones, carry the tens (remainders)
for ($i = 0; $i < $mLen; ++$i) {
$sum = ((int)$num1[$i] + (int)$num2[$i]);
if (isset($output[$i])) {
$sum += $output[$i];
}
$output[$i] = $sum % 10;
if ($sum > 9) {
$output[$i + 1] = 1;
}
}
// convert the array to string and reverse it
$output = strrev(implode('', $output));
// substring the decimal digits from the result, pad if necessary (if $scale > amount of
actual decimals)
// next, since actual zero values can cause a problem with the substring values, if so, just
simply give '0'
// next, append the decimal value, if $scale is defined, and return result
$decimal = str_pad(substr($output, -$dLen, $scale), $scale, '0');
$output = (($mLen - $dLen < 1) ? '0' : ($dLen ? substr($output, 0, -$dLen) :
$output));
$output .= (($dLen && $scale > 0) ? '.' . $decimal : '');
return $output;
}
}
?>