简体   繁体   English

JavaScript 中大数的除法和余数

[英]Division and remainder of large numbers in JavaScript

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.但我发现它对于 JavaScript 来说太长了几个数字。 ie it's getting rounded to zero.即它四舍五入为零。

Is there a way around this other than using a 26kb library like BigInteger.js ?除了使用像BigInteger.js这样的 26kb 库之外,还有其他解决方法吗?

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:您可以将数字分成 10 位数字的块(从右边开始)并对块进行模块化运算,最后合并结果:

1551690021432628813 = 155169002 * 10**10 + 1432628813

Hence因此

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

(Which equals 13 ). (等于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:以下是 Python 语言(我比较流利),但应该很容易翻译成 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对于模数为64的特殊情况,有一个非常简单的方法: 64 divides 10**6所以,绝对总是

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.只要模数是 2 的幂,类似的说法就成立。

thank you John Coleman谢谢约翰科尔曼

javascript version: javascript 版本:

    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;
        }
    }

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*. JavaScript 的数字( IEEE-754双精度二进制浮点数)在那个规模上并不准确,而这些是 JavaScript 拥有的唯一一种数字*。 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).一旦你超过Number.MAX_SAFE_INTEGER + 1 (9,007,199,254,740,992),JavaScript 的数字就不能再表示每个整数(例如,不能表示 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. * 除了类型化数组的元素类型之外,这些对您没有帮助,原因有二:1. Uint32没有类型化数组,最大整数是Uint64 ,以及 2. 一旦您对条目,您正在将其转换为标准数字。

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

There are some workarounds, but generally it is easiest to use a library Read more有一些解决方法,但通常最简单的方法是使用库阅读更多

BigInt(1551690021432628813) % 64 BigInt(1551690021432628813) % 64

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM