5

I'm trying to get the remainder of a large number, for example:

1551690021432628813 % 64

But I find that the it's a couple of digits too long for JavaScript. i.e. it's getting rounded to zero.

Is there a way around this other than using a 26kb library like BigInteger.js?

Sean H
  • 1,045
  • 1
  • 14
  • 32

6 Answers6

4

thank you John Coleman

javascript version :

    function calculateMod(str, mod) {
        var n = str.length;
        if (n <= 10) {
            return parseInt(str) % mod;
        }
        else {
            var first = str.substring(0, n - 10)
            var second = str.substring(n - 10)
            return (calculateMod(first, mod) * (Math.pow(10, 10) % mod) + parseInt(second) % mod) % mod;
        }
    }
Fariborz Korevli
  • 439
  • 5
  • 16
3

You could break the number into chunks of 10 digits (from the right) and do the modular arithmetic on the chunks, combining the result at the end:

1551690021432628813 = 155169002 * 10**10 + 1432628813

Hence

1551690021432628813 % 64 = (155169002 % 64 * (10**10) % 64  + 1432628813 % 64) % 64

(Which equals 13).

You could write a recursive function that implements this idea. The following is in Python (which I am more fluent in) but should be easily translated into JavaScript:

def remainder(s,m):
    #computes int(s) % m, while just using small numbers
    #s is a string and m is an integer

    n = len(s)
    if n <= 10:
        return int(s) % m
    else:
        first = s[:n-10] #first n-10 digits in s
        second = s[-10:] #last 10 digits
        return (remainder(first,m) * ((10**10) % m) + int(second) % m) % m

For the special case that the modulus is 64, there is an exceptionally easy approach: 64 divides 10**6 so, absolutely always

n % 64 == (last 6 digits of n) % 64

For example,

1551690021432628813 % 64 = 628813 % 64 = 13

Similar remarks hold whenever the modulus is a power of 2.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
1

You'd have to use a library (like that one you found). JavaScript's numbers (IEEE-754 double-precision binary floating point) are just not accurate at that scale, and those are the only kind of number JavaScript has*. Once you get past Number.MAX_SAFE_INTEGER + 1 (9,007,199,254,740,992), JavaScript's numbers cannot represent every integer anymore (for instance, can't represent 9,007,199,254,740,993).


* Other than the element type of a typed array, but those don't help you with this for two reasons: 1. There's no typed array for Uint64, the biggest integer is Uint32, and 2. Once you're performing math operations on the entry, you're converting it to standard number.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks for the explanation. I can't use a library as large as the ones I've found out there. I guess a good workaround would be a library that only offers the operation I need, i.e. remainder – Sean H Jul 06 '17 at 12:07
  • @Seano: FWIW, [bignumber.js](https://github.com/MikeMcl/bignumber.js/) is "8K minified and gzipped." That's nothing in most cases in today's world. (I've never used it, it's just the one I happen to know about.) – T.J. Crowder Jul 06 '17 at 12:10
  • I appreciate that but I can't use gzip. Minified it's still 26kb – Sean H Jul 06 '17 at 12:16
  • @Seano: You'd have to be using **amazingly** outdated technology not to be able to use gzip; on-the-fly gzip is a web server feature present in any half-decent web server. But their website is well out of date or it's a typo; looks to me like the minified version is 85k which gzips to 19k on the wire. Which is still not big in the modern world -- but it's not 8k, either! :-) – T.J. Crowder Jul 07 '17 at 06:58
0

// you can use the built-in BigInt object
console.log(Number(1551690021432628813n % 64n));
pank
  • 132
  • 1
  • 3
-1

There are some workarounds, but generally it is easiest to use a library Read more

K. Kirsz
  • 1,384
  • 10
  • 11
  • The link above axplains how you can implement the "string-based division" manually. Did you consider this approach? – K. Kirsz Jul 06 '17 at 12:11
-1

BigInt(1551690021432628813) % 64

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 08 '22 at 11:46