如何在JavaScript中添加两个大数?

8

我有两个文本框,每个都可以输入最多一千位数字。

现在我想把这两个数字加起来。我的问题是,我应该使用什么数据类型来存储结果?

我尝试过这样做:

<script>
   var x = 'Thousand digit of number'
    var y = 'Thousand digit of number'
    var z = x + y
</script>

但我得到的结果是指数形式的。如何存储和显示它?


3
使用现有的bug编号库之一。 - Sirko
你的数字有多大? - Rehan Shikkalgar
我试图输入数字,但它没有发布我的问题,这就是为什么我改变了它。@LKTN.25 - Swapnil Patil
3
可能是 Javascript summing large integers 的重复问题。 - Null
JavaScript 中可以安全使用的最大数字是 Number.MAX_SAFE_INTEGER。你在计算什么需要用到 10 个谷歌数大小的数字?能否简化?还有一些库,比如 http://mikemcl.github.io/decimal.js/,可以处理 JavaScript 中的大数字。 - Emil S. Jørgensen
显示剩余4条评论
10个回答

13

另一种解决方案,因为它更快、更干净。

function add(A, B) {
  const AL = A.length
  const BL = B.length
  const ML = Math.max(AL, BL)

  let carry = 0, sum = ''

  for (let i = 1; i <= ML; i++) {
    let a = +A.charAt(AL - i)
    let b = +B.charAt(BL - i)

    let t = carry + a + b
    carry = t/10 |0
    t %= 10

    sum = (i === ML && carry)
      ? carry*10 + t + sum
      : t + sum
  }

  return sum
}


> add(
'9999999999999999999999999999999999999999999999999999999999999999999999999999',
'999999999999999999999999999999999999999'
)

> "10000000000000000000000000000000000000999999999999999999999999999999999999998"

如果要避免以零开始,可以返回 sum.startsWith("0") ? sum.substring(1):sum; - Devmaleeq
@Malik 它返回了哪些值给你,导致出现了前导 0 - Qwerty

7

2

这里有另一种解决方案,与互联网上可以找到的其他解决方案并没有太大差别(请注意,它不能处理负数!):

function sums(arg1, arg2) {
 var sum = "";
 var r = 0;
 var a1, a2, i;

 // Pick the shortest string as first parameter and the longest as second parameter in my algorithm
 if (arg1.length < arg2.length) {
  a1 = arg1;
  a2 = arg2;
 }
 else {
  a1 = arg2;
  a2 = arg1;
 }
 a1 = a1.split("").reverse();
 a2 = a2.split("").reverse();

 // Sum a1 and a2 digits
 for (i = 0; i < a2.length; i++) {
  var t = ((i < a1.length) ? parseInt(a1[i]) : 0) + parseInt(a2[i]) + r;
  
  sum += t % 10;

  r = t < 10 ? 0 : Math.floor(t / 10);
 }
 // Append the last remain
 if (r > 0)
  sum += r;

 sum = sum.split("").reverse();
 
 // Trim the leading "0"
 while (sum[0] == "0")
  sum.shift();

 return sum.length > 0 ? sum.join("") : "0";
}

// Test
function testEquals(expected, actual) {
 if (expected == actual)
  console.log("OK: " + expected);
 else
  console.error("ERROR: " + expected + " != " + actual);
}

testEquals("100", sums("99", "1"));
testEquals("100", sums("00099", "0001"));
testEquals("10000000000", sums("9999999999", "1"));
testEquals("10000010101", sums("9999999999", "10102"));
testEquals("0", sums("0", "0"));
testEquals("1", sums("0", "1"));
testEquals("9", sums("8", "1"));
testEquals("9", sums("1", "8"));
testEquals("10000000000000000000000000000000000000000", sums("9999999999999999999999999999999999999999", "1"));


1

将数字作为字符串输入,并将每个字符作为数组相加,类似于这样:

 function add() {
        document.getElementById("demo").innerHTML = "";
        var x = document.getElementById("txt1").value;
        var y = document.getElementById("txt2").value;
        var len;
        var lenx = x.length;
        var leny = y.length;
        var x1,y1,rem,div=0;
        if(lenx>leny) len = lenx; else len = leny;

        for(var i=0;i<len;i++){
            if(i>=lenx) x1  = 0;
            else x1 = parseInt(x[lenx-i-1]);
            if(i>=leny) y1 = 0;
            else y1 = parseInt(y[leny-i-1]);
            rem = (x1+y1+div)%10;
            div = Math.floor((x1 + y1+div)/10);
            document.getElementById("demo").innerHTML = rem + document.getElementById("demo").innerHTML;
        }
       if(div>0){
            document.getElementById("demo").innerHTML = div + document.getElementById("demo").innerHTML;
       }
    }

这是代码:https://jsfiddle.net/mtsL1k2x/5/

注意:此代码仅适用于自然数。您可以根据输入进行修改。


0

0
function add(a, b) {
    a = a.split("").reverse();
    b = b.split("").reverse();
    let maxLen=Math.max(a.length, b.length);
    let sum = [];
    let remainder = 0;
    for (let i = 0; i < maxLen; i++) {
      let x = parseInt(a[i]) ? parseInt(a[i]) : 0;
      let y = parseInt(b[i]) ? parseInt(b[i]) : 0;
      let digit = (x + y + remainder) % 10;
      remainder = Math.floor((x + y + remainder) / 10);
      sum.unshift(digit);
    }
    if (remainder) {sum.unshift(remainder)}
    
    return sum.join("");
  }

0

function add(a, b){
  let sum = "";
  let remainder = 0;
  a = a.split("");
  b = b.split("");
  while (a.length || b.length || remainder) {
    remainder += ~~a.pop() + ~~b.pop();
    sum = (remainder % 10) + sum;
    remainder = remainder > 9;
  }
  return sum;
}

const sum = add("9999999999999999999999999999999999999999999999999999999999999999999999999999", "999999999999999999999999999999999999999");

console.log({sum})


0

如果你想在不使用BigInt或任何第三方库的情况下完成这个任务,那么我认为你不需要将其转换为数组,你可以使用charAt()函数在字符串中的每个位置添加单个字符。你需要使用for循环,从最大值开始递减到最小值。以下是代码片段:

function add(a, b) {
let sum='';
 let z,x;
 let r=0;
 if (a.length>=b.length){
   z=a;
   x=b;
 }
 else{
   z=b;
   x=a;
 };
 let p=x.length;
 for (let i=z.length;i>0;i--){
   let t=((p>0)?parseInt(x.charAt(p-1)):0)+parseInt(z.charAt(i-1))+r;
   sum=(t%10)+sum;
   r=t<10?0:Math.floor(t/10);
   p=p-1;
 };
 if (r>0){sum=r+sum};
 return sum;

};

-2
function add(x, y) {
    //this function adds two extremely large numbers, negative and/or positive
    var temp, borrow=false, bothNeg=false, oneNeg=false, neg=false;
    if (x < 0 && y < 0) { bothNeg = true; x = -x; y = -y; } 
    else if (x < 0 || y < 0) {
        oneNeg = true;
        if (Math.abs(x) == Math.abs(y)) { x = 0; y = 0; }
        else if (x < 0 && Math.abs(x) > Math.abs(y)) { neg = true; x = -x; y = -y; }
        else if (x < 0 && Math.abs(x) < Math.abs(y)) { temp = y; y = x; x = temp; }
        else if (y < 0 && Math.abs(x) < Math.abs(y)) { neg = true; temp = y; y = -x; x = -temp; }
    }
    x = parseInt(x*1000000000/10).toString();
    y = parseInt(y*1000000000/10).toString();
    var lenx=x.length, leny=y.length, len=(lenx>leny)?lenx:leny, sum="", div=0, x1, y1, rem;
    for (var i = 0; i < len; i++) {
        x1 = (i >= lenx) ? 0 : parseInt(x[lenx-i-1]);
        y1 = (i >= leny) ? 0 : parseInt(y[leny-i-1]);
        y1 = (isNaN(y1)) ? 0 : y1;
        if (oneNeg) y1 = -y1;
        if (borrow) x1 = x1 - 1;
        if (y < 0 && x1 > 0 && Math.abs(x1) >= Math.abs(y1)) { borrow=false; div=0; }
        if (y < 0 && y1 <= 0 && (x1 < 0 || Math.abs(x1) < Math.abs(y1))) { borrow=true; rem=(x1+y1+div+10)%10; div=10; }
        else { rem=(x1+y1+div)%10; div=Math.floor((x1+y1+div)/10); }
        sum = Math.abs(rem).toString() + sum;
    }
    if (div > 0) sum = div.toString() + sum;
    sum = parseFloat(sum*10/1000000000);
    if (bothNeg || neg) sum = -sum;
    return sum;
}

它是如何工作的?这不会给出预期结果add(9999999999999999999999999999999999999999999999999999999999999999999999999999,999999999999999999999999999999999999999) - Qwerty

-3
 <body>
<p>Click the button to calculate x.</p>
<button onclick="myFunction()">Try it</button>
<br/>
<br/>Enter first number:
<input type="text" id="txt1" name="text1">Enter second number:
<input type="text" id="txt2" name="text2">
<p id="demo"></p>
<script>
  function myFunction() {
    var y = document.getElementById("txt1").value;
    var z = document.getElementById("txt2").value;
    var x = +y + +z;
    document.getElementById("demo").innerHTML = x;
  }
</script>

https://jsfiddle.net/Sanjeevgaut/mtsL1k2x/


你能解释一下为什么 +y+z 会有所不同吗? - Null
input up to thousand digits - mudin
如果您不加上+,它将被视为字符串,只有在添加+var时才会被视为数字。 - Sanjeev Gautam
嘿,我希望我的解决方案运行良好?我也分享了工作链接。 - Sanjeev Gautam
1
他不想要以指数形式获得结果。尝试输入大数字。 - mudin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接