Reputation: 139
I am trying to understand why the modulo operation does not work as expected :
I need to validate an IBAN, and the algoritthm includes doing a modulo.
According to Wikipedia : enter link description here
3214282912345698765432161182 mod 97 = 1
According to my Windows calculator :: 3214282912345698765432161182 mod 97 = 1
BUT when I do it in JS I get 65 :
var result = 3214282912345698765432161182 % 97;
console.log(result);
// result is 65
Why am I getting 65 and not 1 in JS?
Upvotes: 5
Views: 3442
Reputation: 2153
See other answers that adress your direct question. Here's how you can solve your actual problem if you want to do it yourself. There's probably a library that already does that out there, but there's a chance it uses same approach as described below.
Quoting the very wikipedia page you linked to:
Any computer programming language or software package that is used to compute D mod 97 directly must have the ability to handle integers of more than 30 digits. In practice, this can only be done by software that either supports arbitrary-precision arithmetic or that can handle 220 bit (unsigned) integers, features that are often not standard. If the application software in use does not provide the ability to handle integers of this size, the modulo operation can be performed in a piece-wise manner (as is the case with the UN CEFACT TBG5 Javascript program).
Let's see how you could implement this approach with an example:
D = 3214282912345698765432161182
Let's split this number to four parts:
P1 = 321428291 // first 9 digits
P2 = 2345698 // next 7 digits
P3 = 7654321 // next 7 digits
P4 = 61182 // last 5 digits
Then, according to wikipedia, D % 97 == 1
, if following steps lead you to N % 97 == 1
:
Construct N from the first 9 digits of D (P1)
N = 321428291
Calculate N mod 97 = 70
Construct a new 9-digit N from the above result (step 2) followed by the next 7 digits of D (P2).
N = 702345698
Construct a new 9-digit N from the above result (step 4) followed by the next 7 digits of D(P3).
N = 297654321
Construct a new N from the above result (step 6) followed by the remaining 5 digits of D (P4)
N = 2461182
From step 8, the final result is D mod 97 = 1 and the IBAN has passed this check digit test.
Here's an easy ES6 implementation of similar approach provided by dfsq:
function checkIBAN(iban) {
const parts = iban.match(/.{1,6}/g);
return parts.reduce((prev, curr) => Number(prev + curr) % 97, '');
}
console.log(checkIBAN("3214282912345698765432161182"));
Upvotes: 3
Reputation: 53
This library may solve your issue or install via npm
npm install big-integer
A snippet code runs in node
var bigInt = require("big-integer");
var largeNumber = bigInt("3214282912345698765432161182");
console.log(largeNumber.divmod(97).remainder.value)
The output is 1
Upvotes: 0
Reputation: 1097
JavaScript highest integer value without losing precision is
+/- 9007199254740991
Numbers which are less than 2^53 in magnitude can be represented in Number type.
You can check this by running Number.MAX_SAFE_INTEGER in browser console.
Integers larger than that will loss their precision if stored directly.
Check this blogpost for how to handle BigIntegers in Javascript.
http://2ality.com/2012/07/large-integers.html
Upvotes: 0
Reputation: 13943
Your number is higher than (2^53)-1 thus it won't be correctly represented.
You can use the function Number#isSafeInteger
to check if it is safe to use this number
const isSafe = Number.isSafeInteger(3214282912345698765432161182);
console.log(isSafe);
Upvotes: 6