1、最近几天,在机试时候的一个面试题,设计一个高精度加法的函数,支持长数字相加不损失精度,忽略负数(请不要使用 bcadd 等自带函数)。
2、查看 PHP 官网,bcadd — 两个任意精度数字的加法计算。如图1
3、最终实现代码如下,期待于后续有时间后继续完善,现阶段对于请求参数的容错处理上做得还不够,且不支持负数
<?php function highPrecisionAdd(string $number1, string $number2, $scale = null) { // 提取出整数与小数 $numArr1 = explode('.', $number1); $numArr2 = explode('.', $number2); $result = []; // 计算小数的最长长度 $decimalMaxLen = max(strlen($numArr1[1]), strlen($numArr2[1])); // 判断 $scale 是否为 null,如果是,则设置其为结果中小数点后的小数位数 if ($scale === null) { $scale = $decimalMaxLen; } // 删除前导零并反转整数,然后在末尾连接小数 $number1 = strrev(ltrim($numArr1[0], '0') . str_pad($numArr1[1], $decimalMaxLen, '0')); $number2 = strrev(ltrim($numArr2[0], '0') . str_pad($numArr2[1], $decimalMaxLen, '0')); // 计算需要处理的最长长度 $maxLen = max(strlen($number1), strlen($number2)); // 填充两个数字,使它们的长度相等(都等于 $maxLen) $number1 = str_pad($number1, $maxLen, '0'); $number2 = str_pad($number2, $maxLen, '0'); // 处理每个数字,保留个位,携带十位(余数) for($i = 0; $i < $maxLen; $i++) { $sum = ((int) $number1[$i] + (int) $number2[$i]); if (isset($result[$i])) { $sum += $result[$i]; } $result[$i] = $sum % 10; if ($sum > 9) { $result[$i + 1] = 1; } } // 将数组转换为字符串并将其反转 $result = strrev(implode($result)); // 计算出小数 $decimal = str_pad(substr($result, -$decimalMaxLen, $scale), $scale, '0'); // 计算出整数 $can = (($maxLen - $decimalMaxLen < 1) ? '0' : substr($result, 0, -$decimalMaxLen)); // 拼接整数与小数 $result = $can . (($scale > 0) ? '.' . $decimal : ''); return $result; } echo highPrecisionAdd('64474.47265', '24562.45124'); ?>
4、64474.47265 与 24562.45124 相加,运行结果等于:89036.92389,符合预期。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/250642.html