我试着用JS的模函数进行计算,但没有得到正确的结果(应该是1)。这是一段硬编码的代码。
var checkSum = 210501700012345678131468;alert(checkSum % 97);Result: 66
var checkSum = 210501700012345678131468;
alert(checkSum % 97);
Result: 66
有什么问题吗?你好,贝内迪克特
uhry853o1#
对于一个IBAN计算形式,一个普通的银行帐号,我最终得到一个包含在字符串数据类型中的非常大的数字。从这个大的数字,我必须找到其余的时候,除以97 ->大的数字% 97。当我将数据类型转换为整数时,我会得到一个溢出,导致一个负整数,并最终得到一个错误的rest值。当我看到一些冗长的代码片段(也给出了错误的结果)时,我忍不住分享了我自己的代码。信用卡转到Finding Modulus of a Very Large Number with a Normal Number
modulo: function(divident, divisor) { var partLength = 10; while (divident.length > partLength) { var part = divident.substring(0, partLength); divident = (part % divisor) + divident.substring(partLength); } return divident % divisor;}
modulo: function(divident, divisor) {
var partLength = 10;
while (divident.length > partLength) {
var part = divident.substring(0, partLength);
divident = (part % divisor) + divident.substring(partLength);
}
return divident % divisor;
注意:我在这里使用10个位置,因为这比JavaScript中的最大整数的15个(和一些)位置要小,它会导致一个大于97的数字,这是一个很好的整数。前两个论点很重要。
mjqavswn2#
对贝内迪克特的版本进行了一系列改进:cRest += '' + cDivident;是一个bug修复; parseInt(divisor)可以将两个参数都作为字符串传递;检查字符串末尾是否为空,使其始终返回数值;添加了var语句,所以它不使用全局变量;将foreach转换为旧样式,以便它在使用旧JavaScript的浏览器中工作;修复了cRest == 0;错误(感谢@Dan.StackOverflow)。
cRest += '' + cDivident;
parseInt(divisor)
cRest == 0;
function modulo(divident, divisor) { let cDivident = ''; let cRest = ''; for (let i in divident) { let cChar = divident[i]; let cOperator = cRest + '' + cDivident + '' + cChar; if (cOperator < parseInt(divisor)) { cDivident += '' + cChar; } else { cRest = cOperator % divisor; if (cRest == 0) { cRest = ''; } cDivident = ''; } } cRest += '' + cDivident; if (cRest == '') { cRest = 0; } return cRest;}
function modulo(divident, divisor) {
let cDivident = '';
let cRest = '';
for (let i in divident) {
let cChar = divident[i];
let cOperator = cRest + '' + cDivident + '' + cChar;
if (cOperator < parseInt(divisor)) {
cDivident += '' + cChar;
} else {
cRest = cOperator % divisor;
if (cRest == 0) {
cRest = '';
cDivident = '';
if (cRest == '') {
cRest = 0;
return cRest;
bttbmeg03#
对于那些只想在ES6中复制和粘贴工作(功能)解决方案以检查IBAN的人:
function isIBAN(s){ const rearranged = s.substring(4,s.length) + s.substring(0,4); const numeric = Array.from(rearranged).map(c =>(isNaN(parseInt(c)) ? (c.charCodeAt(0)-55).toString() : c)).join(''); const remainder = Array.from(numeric).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % 97,0); return remainder === 1;}
function isIBAN(s){
const rearranged = s.substring(4,s.length) + s.substring(0,4);
const numeric = Array.from(rearranged).map(c =>(isNaN(parseInt(c)) ? (c.charCodeAt(0)-55).toString() : c)).join('');
const remainder = Array.from(numeric).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % 97,0);
return remainder === 1;}
你甚至可以把它写成一行程序。取模运算是在存储实际数字的整数数组上执行的(divident,作为字符串应用于函数):
divident
function modulo(divident, divisor){ return Array.from(divident).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % divisor,0);};
function modulo(divident, divisor){
return Array.from(divident).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % divisor,0);
};
这是因为模在加法、减法和乘法上是分布的:
编译到ES 5的IBAN函数看起来像:
function (s) { var rearranged = s.substring(4, s.length) + s.substring(0, 4); var numeric = Array.from(rearranged).map(function (c) { return (isNaN(parseInt(c)) ? (c.charCodeAt(0) - 55).toString() : c); }).join(''); var remainder = Array.from(numeric).map(function (c) { return parseInt(c); }).reduce(function (remainder, value) { return (remainder * 10 + value) % 97; }, 0); return remainder === 1;};
function (s) {
var rearranged = s.substring(4, s.length) + s.substring(0, 4);
var numeric = Array.from(rearranged).map(function (c) { return (isNaN(parseInt(c)) ? (c.charCodeAt(0) - 55).toString() : c); }).join('');
var remainder = Array.from(numeric).map(function (c) { return parseInt(c); }).reduce(function (remainder, value) { return (remainder * 10 + value) % 97; }, 0);
return remainder === 1;
yhuiod9q4#
看起来你成了这件事的受害者What is JavaScript's highest integer value that a Number can go to without losing precision?只是重申一下另一个线程中的内容:它们是64位浮点值,最大的精确整数值是2^53。然而,从规范部分[8.5:编号类型]:某些ECMAScript运算符仅处理−2^31到2^31−1(含)或0到2^32−1(含)范围内的整数。这些运算符接受Number类型的任何值,但首先将每个此类值转换为2^32个整数值之一。请分别参见第0节和第0节中对ToInt32和ToUint32运算符的描述但功劳归功劳。吉米在那里得到了公认的答案,因为他做了跑腿的工作(嗯,谷歌搜索)。
mm5n2pyu5#
最后,我的解决方案:
function modulo (divident, divisor) { cDivident = ''; cRest = ''; for each ( var cChar in divident ) { cOperator = cRest + '' + cDivident + '' + cChar; if ( cOperator < divisor ) { cDivident += '' + cChar; } else { cRest = cOperator % divisor; if ( cRest == 0 ) cRest = ''; cDivident = ''; } } return cRest;}
function modulo (divident, divisor) {
for each ( var cChar in divident ) {
cOperator = cRest + '' + cDivident + '' + cChar;
if ( cOperator < divisor ) {
if ( cRest == 0 ) cRest = '';
tyg4sfes6#
Silent Matt为Big Integers开发了一个JavaScript library。它也可以解决这个问题。
6条答案
按热度按时间uhry853o1#
对于一个IBAN计算形式,一个普通的银行帐号,我最终得到一个包含在字符串数据类型中的非常大的数字。从这个大的数字,我必须找到其余的时候,除以97 ->大的数字% 97。
当我将数据类型转换为整数时,我会得到一个溢出,导致一个负整数,并最终得到一个错误的rest值。当我看到一些冗长的代码片段(也给出了错误的结果)时,我忍不住分享了我自己的代码。信用卡转到Finding Modulus of a Very Large Number with a Normal Number
注意:我在这里使用10个位置,因为这比JavaScript中的最大整数的15个(和一些)位置要小,它会导致一个大于97的数字,这是一个很好的整数。前两个论点很重要。
mjqavswn2#
对贝内迪克特的版本进行了一系列改进:
cRest += '' + cDivident;
是一个bug修复;parseInt(divisor)
可以将两个参数都作为字符串传递;检查字符串末尾是否为空,使其始终返回数值;添加了var语句,所以它不使用全局变量;将foreach转换为旧样式,以便它在使用旧JavaScript的浏览器中工作;修复了cRest == 0;
错误(感谢@Dan.StackOverflow)。bttbmeg03#
对于那些只想在ES6中复制和粘贴工作(功能)解决方案以检查IBAN的人:
你甚至可以把它写成一行程序。
取模运算是在存储实际数字的整数数组上执行的(
divident
,作为字符串应用于函数):这是因为模在加法、减法和乘法上是分布的:
编译到ES 5的IBAN函数看起来像:
yhuiod9q4#
看起来你成了这件事的受害者What is JavaScript's highest integer value that a Number can go to without losing precision?
只是重申一下另一个线程中的内容:
它们是64位浮点值,最大的精确整数值是2^53。然而,从规范部分[8.5:编号类型]:
某些ECMAScript运算符仅处理−2^31到2^31−1(含)或0到2^32−1(含)范围内的整数。这些运算符接受Number类型的任何值,但首先将每个此类值转换为2^32个整数值之一。请分别参见第0节和第0节中对ToInt32和ToUint32运算符的描述
但功劳归功劳。吉米在那里得到了公认的答案,因为他做了跑腿的工作(嗯,谷歌搜索)。
mm5n2pyu5#
最后,我的解决方案:
tyg4sfes6#
Silent Matt为Big Integers开发了一个JavaScript library。它也可以解决这个问题。