Modulo в JavaScript - большое количество
Я пытаюсь вычислить с помощью модульной функции JS, но не получим правильный результат (который должен быть 1). Вот жесткий код кода.
var checkSum = 210501700012345678131468;
alert(checkSum % 97);
Result: 66
В чем проблема?
С уважением,
Бенедикта
Ответы
Ответ 1
Множество улучшений версии Бенедикта: "cRest + = '' + cDivident; является исправлением; parseInt (divisor) позволяет передавать оба аргумента в виде строк; проверка пустой строки в конце делает ее всегда возвращать числовые значения; добавлены инструкции var, чтобы не использовать глобальные переменные; преобразованный foreach в старый стиль, так что он работает в браузерах со старым Javascript; исправлено cRest == 0; ошибка (спасибо @Dan.StackOverflow).
function modulo (divident, divisor) {
var cDivident = '';
var cRest = '';
for (var i in divident ) {
var cChar = divident[i];
var 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;
}
Ответ 2
Для формы расчета IBAN нормальный номер банковского счета я заканчивается очень большим числом, содержащимся в строковом типе данных. Из этого большого числа я должен найти остальное, когда делится на 97 → большое количество% 97.
Как только я конвертирую тип данных в целое число, я получаю переполнение, в результате чего получается отрицательное целое число и, в конечном итоге, неправильное значение останова. Поскольку я видел некоторые многословные фрагменты кода (что также давало неправильный результат), я не мог удержаться, чтобы поделиться своим собственным. Кредиты отправляются Поиск модуля очень большого числа с нормальным номером
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;
}
N.B.
Здесь я использую 10 позиций, так как это меньше, чем 15 (и некоторые) положения max integer в JavaScript, это приводит к числу, превышающему 97, и это хороший круглый номер. Первые два аргумента имеют значение.
Ответ 3
похоже, что вы стали жертвой этого: Что такое максимальное целочисленное значение JavaScript, которое Number может идти без потери точности?
просто повторить, что в другом потоке:
это 64-битные значения с плавающей запятой, наибольшее точное интегральное значение - 2 ^ 53. однако из раздела spec [8.5: Number Type]:
Некоторые операторы ECMAScript имеют дело только с целыми числами в диапазоне от -2 ^ 31 до 2 ^ 31-1 включительно или в диапазоне от 0 до 2 ^ 32-1 включительно. Эти операторы принимают любое значение типа Number, но сначала преобразуют каждое такое значение в одно из 2 ^ 32 целых значений. См. Описания операторов ToInt32 и ToUint32 в разделах 0 и 0 соответственно
Но кредит, где должен быть кредит. Джимми получил принятый ответ там для выполнения работы (ну, поиск в Интернете).
Ответ 4
Наконец, мое решение:
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;
}
Ответ 5
Silent Matt разработал Javascript библиотеку для больших целых чисел. Он также может решить эту проблему.
Ответ 6
Для тех, кто просто хочет скопировать и вставить рабочее (функциональное) решение в 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;}
Вы даже можете записать его как однострочный.
Операция modulo выполняется в массиве целых чисел, сохраняющих фактическое число (divident
, применяемое как строка для функции):
function modulo(divident, divisor){
return Array.from(divident).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % divisor,0);
};
Это работает, потому что Modulo является дистрибутивным над добавлением, вычитанием и умножением:
- (a + b)% m = ((a% m) + (b% m))% m
- (a-b)% m = ((a% m) - (b% m))% m
- (ab)% m = ((a% m) (b% m))% m
Функция IBAN, переданная в ES5, выглядит следующим образом:
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;
};