According to Google Calculator (-13) % 64 is 51.
According to Javascript (see this JSBin) it is -13.
How do I fix this?
According to Google Calculator (-13) % 64 is 51.
According to Javascript (see this JSBin) it is -13.
How do I fix this?
Number.prototype.mod = function(n) {
return ((this%n)+n)%n;
};
Taken from this article: The JavaScript Modulo Bug
Using Number.prototype is SLOW, because each time you use the prototype method your number is wrapped in an Object. Instead of this:
Number.prototype.mod = function(n) {
return ((this % n) + n) % n;
}
Use:
function mod(n, m) {
return ((n % m) + m) % m;
}
See: http://jsperf.com/negative-modulo/2
~97% faster than using prototype. If performance is of importance to you of course..
The accepted answer makes me a little nervous because it re-uses the % operator. What if Javascript changes the behavior in the future?
Here is a workaround that does not re-use %:
function mod(a, n) {
return a - (n * Math.floor(a/n));
}
mod(1,64); // 1
mod(63,64); // 63
mod(64,64); // 0
mod(65,64); // 1
mod(0,64); // 0
mod(-1,64); // 63
mod(-13,64); // 51
mod(-63,64); // 1
mod(-64,64); // 0
mod(-65,64); // 63
Though it isn't behaving as you expected, it doesn't mean that JavaScript is not 'behaving'. It is a choice JavaScript made for its modulo calculation. Because, by definition either answer makes sense.
See this from Wikipedia. You can see on the right how different languages chose the result's sign.
I deal with négative a and negative n too
//best perf, hard to read
function modul3(a,n){
r = a/n | 0 ;
if(a < 0){
r += n < 0 ? 1 : -1
}
return a - n * r
}
// shorter code
function modul(a,n){
return a%n + (a < 0 && Math.abs(n));
}
//beetween perf and small code
function modul(a,n){
return a - n * Math[n > 0 ? 'floor' : 'ceil'](a/n);
}
This is not a bug, there's 3 functions to calculate modulo, you can use the one which fit your needs (I would recommend to use Euclidean function)
console.log( 41 % 7 ); // 6
console.log( -41 % 7 ); // -6
console.log( -41 % -7 ); // -6
console.log( 41 % -7 ); // 6
Number.prototype.mod = function(n) {
return ((this%n)+n)%n;
};
console.log( parseInt( 41).mod( 7) ); // 6
console.log( parseInt(-41).mod( 7) ); // 1
console.log( parseInt(-41).mod(-7) ); // -6
console.log( parseInt( 41).mod(-7) ); // -1
Number.prototype.mod = function(n) {
var m = ((this%n)+n)%n;
return m < 0 ? m + Math.abs(n) : m;
};
console.log( parseInt( 41).mod( 7) ); // 6
console.log( parseInt(-41).mod( 7) ); // 1
console.log( parseInt(-41).mod(-7) ); // 1
console.log( parseInt( 41).mod(-7) ); // 6
There is a NPM package that will do the work for you. You can install it with the following command.
npm install just-modulo --save
Usage copied from the README
import modulo from 'just-modulo';
modulo(7, 5); // 2
modulo(17, 23); // 17
modulo(16.2, 3.8); // 17
modulo(5.8, 3.4); //2.4
modulo(4, 0); // 4
modulo(-7, 5); // 3
modulo(-2, 15); // 13
modulo(-5.8, 3.4); // 1
modulo(12, -1); // NaN
modulo(-3, -8); // NaN
modulo(12, 'apple'); // NaN
modulo('bee', 9); // NaN
modulo(null, undefined); // NaN
GitHub repository can be found via the following link:
https://github.com/angus-c/just/tree/master/packages/number-modulo
%is not the modulo operator. It's the remainder operator. There is no modulo operator in JavaScript. So the accepted answer is the way to go. - Redu