Sum of huge numbers

2

I am practicing my javascript in CodeWars and I have come across this question:

  

Write a function that returns the String with the sum of two numbers. The parameters are two numbers but of type String .

Notes:

  • The inputs are large.
  • The inputs are strings containing only numbers.
  • The numbers are positive.

For what I did:

function add(a, b) {
  return (Number(a) + Number(b))+"";
}

For small numbers there is no problem, I pass the tests well, but for large numbers it fails to change the notation.

Tests:

✔ Test Passed: Value == '100'
✔ Test Passed: Value == '8670'
✔ Test Passed: Value == '5'
✘ sumStrings('712569312664357328695151392', '8100824045303269669937') - 
    Expected: '712577413488402631964821329', instead got: '7.125774134884027e+26'
✘ sumStrings('50095301248058391139327916261', '81055900096023504197206408605') - 
    Expected: '131151201344081895336534324866', instead got: '1.3115120134408189e+29' 

Probably a bullshit but I can not think of it. How can I solve this problem?

    
asked by lois6b 01.03.2017 в 10:59
source

3 answers

4

It really does not fail, the sum is done correctly, simply that CodeWars will not want that format as a result.

For example:

The number 7.125774134884027e+26 is the same as 712577413488402631964821329 but simply with different notation.

I have not got another solution less complex than the one I propose below:

function add(num1, num2) {
    num1 = num1.split('');
  num2 = num2.split('');

  num1 = num1.map(function (num) {
    return parseInt(num, 10);
  });

  num2 = num2.map(function (num) {
    return parseInt(num, 10);
  });

    if (num2.length > num1.length) {
    return _add(num2, num1);
  } else {
    return _add(num1, num2)
  }
}

function _add(num1, num2) {
    var num1_idx = num1.length-1;
  var num2_idx = num2.length-1;
  var remainder = 0;

  for (; num1_idx > -1; num1_idx--, num2_idx--) {
    var sum = num1[num1_idx] + remainder;

    if (num2_idx > -1) {
        sum += num2[num2_idx];
    }

        if (sum <= 9 || num1_idx === 0) {
        remainder = 0;
        num1[num1_idx] = sum;
    } else if (sum >= 10) {
        remainder = 1;
      num1[num1_idx] = sum - 10;
    }

    console.log(remainder);
  }

  return num1.join('').replace(/^[0]+/g,"");
}

Using it in the following way:

document.write(add("712577413488402631964821329", "712577413488402631964821329"));

You have the GitHub with the creator of this method here

Another solution that I have found is to use external libraries for it like BigInteger and be able to use it like this:

var n = bigInt("91942213363574161572522430563301811072406154908250")
    .plus("91942213363574161572522430563301811072406154908250");
    
answered by 01.03.2017 / 11:38
source
1

I solved it by imitating the school method:

I take the least significant number of both numbers. I add them, write down the unit and, if necessary, reserve one. This is equivalent to iterating over the longest string and removing the least significant number from both string, adding them, obtaining the ten and then iterating again adding the ten (which at the beginning is worth 0).

See the following example:

function sumabigInt(num1,num2) {

            var num1 = String(num1),
                num2 = String(num2),
                acumulado = '',
                arr1 = num1.split(''),
                arr2 = num2.split(''),
                decena = 0,
                maxlength = Math.max(arr1.length, arr2.length);

           var sumadigitos=function(a, b, c) {
                var suma = Number(a) + Number(b) + Number(c),
                    nuevonumero = suma % 10,
                    segundacifra = Math.floor(suma / 10);
                acumulado = String(nuevonumero) + acumulado;
                return segundacifra;
            };

 
            for (var i = 0; i < maxlength; i++) {
                var val1 = arr1.length ? arr1.pop() : 0,
                    val2 = arr2.length ? arr2.pop() : 0;
                decena = sumadigitos(val1, val2, decena);
            }
            if (decena > 0) {
                acumulado = String(decena) + acumulado;
            }
            return acumulado;
 }
console.log(sumabigInt(  '712569312664357328695151392', '8100824045303269669937'));     
 
 

The following example is printing a tablet with jQuery.

jQuery(document).ready(function() {
            var num1 = '712569312664357328695151392',
                num2 = '8100824045303269669937',
                acumulado = '',
                arr1 = num1.split(''),
                arr2 = num2.split(''),
                iteracion = 1,
                decena = 0,
                maxlength = Math.max(arr1.length, arr2.length);

            function sumadigitos(a, b, c) {
                var suma = Number(a) + Number(b) + Number(c),
                    nuevonumero = suma % 10,
                    segundacifra = Math.floor(suma / 10);
                acumulado = String(nuevonumero) + acumulado;
                return segundacifra;
            }

            function imprime(iteracion) {
                var newrow = jQuery('<tr></tr>');
                newrow.append('<td >Iteracion ' + iteracion + '</td>');
                newrow.append('<td >' + arr1.join('') + '</td>');
                newrow.append('<td >' + arr2.join('') + '</td>');
                newrow.append('<td >' + acumulado + '</td>');
                newrow.appendTo('#container');
            }
            imprime(iteracion);
            for (var i = 0; i < maxlength; i++) {
                var val1 = arr1.length ? arr1.pop() : 0,
                    val2 = arr2.length ? arr2.pop() : 0;
                decena = sumadigitos(val1, val2, decena);
                iteracion++;
                imprime(iteracion);
            }
            if (decena > 0) {
                acumulado = String(decena) + acumulado;
                imprime('final');
            }
        });
td {
            border: 1px solid #ccc;
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="container" style="width:550px;font-size:9px;">
            <tr>
                <th width="15%">
                    Comentario
                </th>
                <th width="26%">
                    num1
                </th>
                <th width="26%">
                    num2
                </th>
                <th width="29%">
                    acumulado
                </th>
            </tr>
        </table>

        
    
answered by 01.03.2017 в 12:48
1

JavaScript use double-precision float in working with numbers and can represent numbers in a way Secure between -(2^53 - 1) and 2^53 - 1 . That means that you must work with numbers between -9007199254740991 and 9007199254740991 , for larger numbers you will represent them as what returns CodeWars (scientific notation). If you need to work with larger numbers I recommend using a library like BigNumbers.js .

    
answered by 01.03.2017 в 11:45