根据谷歌计算器(-13)% 64 = 51。

根据Javascript(参见这个JSBin),它是-13。

我怎么解决这个问题?


当前回答

使用数字。prototype很慢,因为每次你使用prototype方法时,你的数字都被包裹在一个Object中。而不是这样:

Number.prototype.mod = function(n) {
  return ((this % n) + n) % n;
}

Use:

function mod(n, m) {
  return ((n % m) + m) % m;
}

参见:https://jsperf.app/negative-modulo/2

比使用原型快97%。当然,如果业绩对你来说很重要的话。

其他回答

有一个NPM包可以帮你完成这项工作。您可以使用以下命令安装它。

NPM install just-modulo—save

从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存储库可以通过以下链接找到:

https://github.com/angus-c/just/tree/master/packages/number-modulo

为了好玩,这里有一个“wrap”函数,它的工作方式有点像模数,除了你也可以指定范围的最小值(而不是0):

const wrap = (value = 0, min = 0, max = 10) =>
  ((((value - min) % (max - min)) + (max - min)) % (max - min)) + min;

基本上就是取真模公式,对其进行偏移,使min值最终为0,然后将min值加回来。

如果有一个值希望保持在两个值之间,则很有用。

接受的答案让我有点紧张,因为它重用了%操作符。如果Javascript在未来改变了行为呢?

下面是一个不重用%的解决方案:

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

JavaScript中的%操作符是余数操作符,而不是模数操作符(主要区别在于负数的处理方式):

-1 % 8 // -1,不是7

修正负模(提醒操作符%)

简化使用ES6箭头功能,没有危险的扩展数字原型

Const mod = (n, m) => (n % m + m) % m; console.log (mod (-90, 360));// 270(不是-90)