设计一个高精度加法的函数,支持长数字相加不损失精度,忽略负数(请不要使用 bcadd 等自带函数)
1、最近几天,在机试时候的一个面试题,设计一个高精度加法的函数,支持长数字相加不损失精度,忽略负数(请不要使用 bcadd 等自带函数)。
2、查看 PHP 官网,bcadd — 两个任意精度数字的加法计算。如图1
3、最终实现代码如下,期待于后续有时间后继续完善,现阶段对于请求参数的容错处理上做得还不够,且不支持负数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <?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,符合预期。
近期评论