模块在Javascript中不起作用

模块在Javascript中不起作用,javascript,Javascript,我试图理解为什么模运算不能按预期工作: 我需要验证一个IBAN,算法包括做一个模运算 根据维基百科: 3214282912345698765432161182模块97=1 根据我的Windows计算器: 3214282912345698765432161182模块97=1 但当我在JS中这样做时,我得到65: var结果=3214282912345698765432161182%97; 控制台日志(结果); //结果是65您的数字高于(2^53)-1,因此无法正确表示 您可以使用功能Numb

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

我需要验证一个IBAN,算法包括做一个模运算

根据维基百科:

3214282912345698765432161182模块97=1

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

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

var结果=3214282912345698765432161182%97;
控制台日志(结果);

//结果是65
您的数字高于(2^53)-1,因此无法正确表示

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

const isSafe=Number.isSafeInteger(3214282912345698765432161182);

控制台日志(isSafe)JavaScript不丢失精度的最大整数值为

+/-9007199254740991

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

您可以通过在浏览器控制台中运行Number.MAX\u SAFE\u INTEGER来检查这一点

如果直接存储,大于该值的整数将丢失其精度

查看这篇博客文章,了解如何在Javascript中处理大整数

这可能会解决您的问题或通过npm进行安装
npm安装大整数

一段代码在节点中运行

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

输出为1

请参阅解决您直接问题的其他答案。如果你想自己解决实际问题,这里有一些方法。可能有一个库已经做到了这一点,但它有可能使用下面描述的相同方法

引用您链接到的内容:

用于直接计算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

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

    N=321428291

  • 计算N mod 97=70

  • 根据上述结果(步骤2)构造一个新的9位N,然后是D(P2)的后7位

    N=702345698

  • 计算N mod 97=29
  • 根据上述结果(步骤4)构造一个新的9位N,然后是D(P3)的下7位

    N=297654321

  • 计算N mod 97=24
  • 根据上述结果(步骤6)构造一个新的N,然后是D(P4)的剩余5位

    N=246182

  • 计算N mod 97=1
  • 从步骤8开始,最终结果为D mod 97=1,且IBAN已通过 这是一个校验数字测试

    下面是一个类似方法的简单ES6实现,由以下人员提供:

    函数checkIBAN(iban){
    const parts=iban.match(/.{1,6}/g);
    返回零件。减少((上一次,当前)=>数量(上一次+当前)%97');
    }
    
    日志(checkIBAN(“3214282912345698765432161182”)这真是一个很大的数字,我想你已经溢出了。是的,这是一个92位的数字。您将需要比原始数字类型更高级的东西…请尝试
    console.log(3214282912345698765432161182)
    …您处于浮动领域,不能期望得到“正确”的结果。Javascript数字只有56位精度。请参阅以获得一些替代实现。当然,下一个问题是,你是如何计算如此大的一个数的模的?@NiettheDarkAbsol如果使用一个处理大整数I的外部库的话guess@NiettheDarkAbsol-有一些方法可以做到这一点,我在回答中描述了一种。很不错的!这里是这个算法更简单的实现:
    函数checkIBAN(iban){const parts=iban.match(/.{1,6}/g);返回parts.reduce((prev,curr)=>Number(prev+curr)%97',)}