没有不值得去解决的问题,也没有不值得去学习的技术!

Design a High-Precision Addition Function for Long Numbers Without Using Built-in Functions Like bcadd

bcadd — Adds two arbitrary precision numbers

1. Recently, during an online assessment, I encountered an interview question: design a high-precision addition function that supports adding long numbers without losing precision and ignores negative numbers (do not use built-in functions like bcadd).

2. Checking the PHP official website, bcadd — Adds two arbitrary precision numbers. As shown in Figure 1.

bcadd — Adds two arbitrary precision numbers
Figure 1

3. The final implementation code is as follows. I plan to refine it further when I have time later. Currently, the fault tolerance for request parameters is insufficient, and negative numbers are not supported.

PHP
<?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. Adding 64474.47265 and 24562.45124 yields a result of 89036.92389, which meets expectations.

 

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系