有道前端面试题:两个很大数如何做加法运算?

写一个函数处理大数据的相加问题,所谓的大数据是指超出了整型,长整型之类的常规数据类型表示范围的数据。实现语言不限。

昨天在网上看到这道题,感觉很奇怪,难道还有什么算法能比原生的符号运算更快?看到这个链接:http://niutuku.com/tech/javaScript/258837.shtml,我测试了一下,大数据函数就出错,速度也明显不行,请教这道题的思路是什么? (链接源代码有笔误,我修改了下,贴在下面)

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
    window.onload = function () {
        console.time("strNumAdd")
        var strAdd = function (srcA, srcB) {
            var i, temp, tempA, tempB, len, lenA, lenB, carry = 0;
            var res = [],
                arrA = [],
                arrB = [],
                cloneArr = [];
            arrA = (srcA + "").split("");
            arrB = (srcB + "").split("");
            arrA.reverse();
            arrB.reverse();
            lenA = arrA.length;
            lenB = arrB.length;
            len = lenA > lenB ? lenB : lenA;
            for (i = 0; i < len; i++) {
                tempA = parseInt(arrA[i], 10);
                tempB = parseInt(arrB[i], 10);
                temp = tempA + tempB + carry;
                if (temp > 9) {
                    res.push(temp - 10);
                    carry = 1;
                } else {
                    res.push(temp);
                    carry = 0;
                }
            }
            cloneArr = lenA > lenB ? arrA : arrB;
            for (; i < cloneArr.length; i++) {
                tempA = parseInt(cloneArr[i], 10);
                temp = tempA + carry;
                if (temp > 9) {
                    res.push(temp - 10);
                    carry = 1;
                } else {
                    res.push(temp);
                    carry = 0;
                }
            }
            return (res.reverse()).join('');
        };
        console.log(strAdd(23909080089709873508234, 9834309800089325675433678))
        console.timeEnd("strNumAdd")


        console.time("normalAdd")
        console.log(23909080089709873508234, 9834309800089325675433678)
        console.timeEnd("normalAdd")

    }
    </script>
</head>
<body>

</body>
</html>
阅读 17.4k
4 个回答

A Javascript library for arbitrary-precision decimal and non-decimal arithmetic
https://github.com/MikeMcl/bignumber.js

一个关于大数运算的 javascript 库。

原生 js 浮点数运算:

0.3 - 0.1                  // 0.19999999999999998

bignumber 运算:

x = new BigNumber(0.3)
x.minus(0.1)               // '0.2'
x.minus(0.6, 20)           // '0'
function add(a, b) {
  var carry = 0, result = [],
      len = Math.max(a.length, b.length), i = len;
  while (i--) {
    var sum = (+a[i - len + a.length]||0) + (+b[i - len + b.length]||0) + carry;
    carry = parseInt(sum / 10);
    result.unshift(sum % 10);
  }
  if (carry) result.unshift(carry);
  return result.join('');
}

这个问题简单debug一下就能发现问题所在了。大数字被表示为科学计数法了,如23909080089709873508234传参进去,在执行arrA = (srcA + "").split("");这句代码的时候,表达式(srcA+"")实际上是“2.3909080089709876e+22”这样的字符串。

回想起大一时候学ACM的时候做的大数相加题。 那个时候我自己想的思路是把大数当字符串输入,每位变成数字相加,有进位就进位,lz给的代码大概也是这个意思。当然高深的算法我没学下去。。可以搜索acm的大数相加,虽然基本上是c++的解法占多数。

这面试题明显是考查ACM方面的算法。。前端考算法都是耍流氓,真想匿名

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏