Modulo无法使用Javascript

时间:2018-03-30 10:56:29

标签: javascript

我试图理解为什么模运算不能按预期工作:

我需要验证IBAN,并且算法包括做模数。

根据维基百科: enter link description here

3214282912345698765432161182 mod 97 = 1

根据我的Windows计算器:: 3214282912345698765432161182 mod 97 = 1

但是当我在JS中这样做时我得到65:

var result = 3214282912345698765432161182 % 97;
console.log(result);
// result is 65

为什么我在JS中获得65而不是1?

4 个答案:

答案 0 :(得分:4)

您的号码高于(2 ^ 53)-1,因此无法正确表示。

您可以使用功能Number#isSafeInteger检查使用此号码是否安全

const isSafe = Number.isSafeInteger(3214282912345698765432161182);

console.log(isSafe);

答案 1 :(得分:1)

查看解决您直接问题的其他答案。如果您想自己动手,可以使用以下方法解决实际问题。可能有一个库已经在那里做了,但它有可能使用如下所述的相同方法。

引用您链接到的the very wikipedia page

  

任何用于直接计算D mod 97的计算机编程语言或软件包都必须能够处理超过30位的整数。实际上,这只能通过支持任意精度算术或可以处理220位(无符号)整数的软件来完成,这些特性通常不是标准的。如果使用的应用程序软件不能提供处理此大小的整数的能力,则可以以分段方式执行模运算(与UN CEFACT TBG5 Javascript程序的情况一样)。

让我们看看你如何用一个例子来实现这个方法:

D = 3214282912345698765432161182

让我们将这个数字分成四部分:

P1 = 321428291 // first 9 digits
P2 = 2345698   // next 7 digits
P3 = 7654321   // next 7 digits
P4 = 61182     // last 5 digits

然后,根据维基百科D % 97 == 1,如果以下步骤引导您N % 97 == 1

  1. 从D(P1)的前9位构造N

    N = 321428291

  2. 计算N mod 97 = 70

  3. 从上面的结果(步骤2)构建一个新的9位数N,接着是 D(P2)的后7位数字。

    N = 702345698

  4. 计算N mod 97 = 29
  5. 从上面的结果(步骤4)构建一个新的9位数N,然后是 D(P3)的下一个7位数。

    N = 297654321

  6. 计算N mod 97 = 24
  7. 从上面的结果(步骤6)构建一个新的N,然后是 D(P4)的剩余5位数

    N = 2461182

  8. 计算N mod 97 = 1
  9.   

    从步骤8开始,最终结果为D mod 97 = 1且IBAN已通过   这个校验位测试。

    这是dfsq提供的类似方法的简单ES6实现:

    function checkIBAN(iban) { 
      const parts = iban.match(/.{1,6}/g); 
      return parts.reduce((prev, curr) => Number(prev + curr) % 97, ''); 
    }
    console.log(checkIBAN("3214282912345698765432161182"));

答案 2 :(得分:0)

JavaScript最高整数值而不会丢失精度

+/- 9007199254740991

数量小于2 ^ 53的数字可以用数字类型表示。

您可以在浏览器控制台中运行 Number.MAX_SAFE_INTEGER 来检查这一点。

如果直接存储,大于此值的整数将失去其精度。

查看此博客文章,了解如何在Javascript中处理BigIntegers。

http://2ality.com/2012/07/large-integers.html

答案 3 :(得分:0)

library可以解决您的问题或通过npm安装 npm install big-integer

代码段在节点

中运行
var bigInt = require("big-integer");
var largeNumber = bigInt("3214282912345698765432161182");
console.log(largeNumber.divmod(97).remainder.value)

输出为1