Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modulo in JavaScript - large number

I try to calculate with JS' modulo function, but don't get the right result (which should be 1). Here is a hardcoded piece of code.

var checkSum = 210501700012345678131468;
alert(checkSum % 97);

Result: 66

Whats the problem here?

Regards, Benedikt

like image 551
Benedikt Avatar asked May 30 '09 15:05

Benedikt


People also ask

How do you do modulo of large numbers?

Given a big number 'num' represented as string and an integer x, find value of “num % x” or “num mod x”. Output is expected as an integer. y: rest of the digits except x.

How do you handle large numbers in JavaScript?

We can deal with large numbers in JavaScript using the data type BigInt. Advantages: It can hold numbers of large size. It perform arithmetic operations.

What is JavaScript BigInt?

BigInt is a primitive wrapper object used to represent and manipulate primitive bigint values — which are too large to be represented by the number primitive.

Does JavaScript have a modulo operator?

In JavaScript, the modulo operation (which doesn't have a dedicated operator) is used to normalize the second operand of bitwise shift operators ( << , >> , etc.), making the offset always a positive value.


2 Answers

For an IBAN calculation form a normal bankaccount number I end up with a very large number contained in a string datatype. From this large number I have to find the rest when divided by 97 -> large number % 97.

As soon as I convert the datatype to an integer I get an overflow resulting in a negative integer and eventually a wrong rest value. As I saw some verbose pieces of code (which also gave wrong outcome), I could not resist to share my own. Credits go to Finding Modulus of a Very Large Number with a Normal Number

modulo: function(divident, divisor) {
    var partLength = 10;

    while (divident.length > partLength) {
        var part = divident.substring(0, partLength);
        divident = (part % divisor) +  divident.substring(partLength);          
    }

    return divident % divisor;
}

N.B. I use 10 positions here as this is smaller than the 15 (and some) positions of max integer in JavaScript, it results in a number bigger than 97 and it's a nice round number. The first two arguments matter.

like image 135
Jaco Boon Avatar answered Sep 19 '22 13:09

Jaco Boon


A bunch of improvements to Benedikt's version: "cRest += '' + cDivident;" is a bugfix; parseInt(divisor) makes it possible to pass both arguments as strings; check for empty string at the end makes it always return numerical values; added var statements so it's not using global variables; converted foreach to old-style for so it works in browsers with older Javascript; fixed the cRest == 0; bug (thanks @Dan.StackOverflow).

function modulo (divident, divisor) {
    var cDivident = '';
    var cRest = '';

    for (var i in divident ) {
        var cChar = divident[i];
        var cOperator = cRest + '' + cDivident + '' + cChar;

        if ( cOperator < parseInt(divisor) ) {
                cDivident += '' + cChar;
        } else {
                cRest = cOperator % divisor;
                if ( cRest == 0 ) {
                    cRest = '';
                }
                cDivident = '';
        }

    }
    cRest += '' + cDivident;
    if (cRest == '') {
        cRest = 0;
    }
    return cRest;
}
like image 25
Gilead Avatar answered Sep 21 '22 13:09

Gilead