views:

1493

answers:

3

Hi! 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

+2  A: 

looks like you've fallen victim to this: http://stackoverflow.com/questions/307179/what-is-javascripts-max-int-whats-the-highest-integer-value-a-number-can-go-to

just to reiterate what's in the other thread:

they are 64-bit floating point values, the largest exact integral value is 2^53. however, from the spec section [8.5: Number Type]:

Some ECMAScript operators deal only with integers in the range −2^31 through 2^31−1, inclusive, or in the range 0 through 2^32−1, inclusive. These operators accept any value of the Number type but first convert each such value to one of 2^32 integer values. See the descriptions of the ToInt32 and ToUint32 operators in sections 0 and 0, respectively

But credit where credit is due. Jimmy got the accepted answer over there for doing the legwork (well, googling).

Jonathan Fingland
So, is there a workaround for this? I can't find anything helpful via google.
Benedikt R.
Couldn't you do a division and calculate the remainder?
gnarf
given that the checksum given above is already above 2^53, you'd have to do something a little more .... interesting... to break up the number *before* performing any operations on it
Jonathan Fingland
+1  A: 

Finally, my solution:

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

    for each ( var cChar in divident ) {
     cOperator = cRest + '' + cDivident + '' + cChar;

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

    }

    return cRest;
}
Benedikt R.
+2  A: 

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.

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;
}
Gilead
thank you for your improvements
Benedikt R.