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