JavaScript % (modulo) 给出负数的负结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4467539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript % (modulo) gives a negative result for negative numbers
提问by Alec Gorge
According to Google Calculator(-13) % 64
is 51
.
根据谷歌计算器(-13) % 64
是51
.
According to Javascript (see this JSBin) it is -13
.
根据 Javascript(请参阅此JSBin),它是-13
.
How do I fix this?
我该如何解决?
回答by Enrique
Number.prototype.mod = function(n) {
return ((this%n)+n)%n;
};
Taken from this article: The JavaScript Modulo Bug
摘自这篇文章:JavaScript Modulo Bug
回答by StuR
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
很慢,因为每次使用原型方法时,您的数字都会被包裹在Object
. 取而代之的是:
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
见:http: //jsperf.com/negative-modulo/2
~97% faster than using prototype. If performance is of importance to you of course..
比使用原型快 97%。如果性能对你来说当然很重要..
回答by Rob Sobers
The %
operator in JavaScript is the remainder operator, not the modulo operator (the main difference being in how negative numbers are treated):
在%
JavaScript中运算符是求余运算符,而不是模运算符(如何负数的处理方式主要区别):
-1 % 8 // -1, not 7
-1 % 8 // -1, not 7
回答by Shanimal
A "mod" function to return a positive result.
返回正结果的“mod”函数。
var mod = function (n, m) {
var remain = n % m;
return Math.floor(remain >= 0 ? remain : remain + m);
};
mod(5,22) // 5
mod(25,22) // 3
mod(-1,22) // 21
mod(-2,22) // 20
mod(0,22) // 0
mod(-1,22) // 21
mod(-21,22) // 1
And of course
而且当然
mod(-13,64) // 51
回答by wisbucky
The accepted answer makes me a little nervous because it re-uses the % operator. What if Javascript changes the behavior in the future?
接受的答案让我有点紧张,因为它重新使用了 % 运算符。如果 Javascript 将来改变行为怎么办?
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
回答by dheerosaur
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.
尽管它的行为不像您预期的那样,但这并不意味着 JavaScript 没有“行为”。这是 JavaScript 为其模计算所做的选择。因为,根据定义,任何一个答案都有意义。
See thisfrom Wikipedia. You can see on the right how different languages chose the result's sign.
从维基百科看到这个。您可以在右侧看到不同的语言如何选择结果的符号。
回答by quasimodo
If x
is an integer and n
is a power of 2, you can use x & (n - 1)
instead of x % n
.
如果x
是整数并且n
是 2 的幂,则可以使用x & (n - 1)
代替x % n
。
> -13 & (64 - 1)
51
回答by JayCrossler
So it seems that if you're trying to mod around degrees (so that if you have -50 degrees - 200 degrees), you'd want to use something like:
因此,似乎如果您尝试修改度数(因此如果您有 -50 度 - 200 度),您可能想要使用以下内容:
function modrad(m) {
return ((((180+m) % 360) + 360) % 360)-180;
}
回答by zessx
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)
这不是错误,有 3 个函数可以计算模数,您可以使用适合您需要的函数(我建议使用欧几里得函数)
Truncating the decimal part function
截断小数部分函数
console.log( 41 % 7 ); // 6
console.log( -41 % 7 ); // -6
console.log( -41 % -7 ); // -6
console.log( 41 % -7 ); // 6
Integer part function
整数部分函数
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
Euclidean function
欧氏函数
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
回答by bormat
I deal with négative a and negative n too
我也处理负 a 和负 n
//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);
}