Ale*_*rge 224 javascript math modulo
根据谷歌计算器 (-13) % 64
是51
.
根据Javascript(参见这个JSBin)它是-13
.
我该如何解决?
Enr*_*que 234
Number.prototype.mod = function(n) {
return ((this%n)+n)%n;
};
Run Code Online (Sandbox Code Playgroud)
Stu*_*tuR 138
使用Number.prototype
是SLOW,因为每次使用原型方法时,您的数字都包含在Object
.而不是这个:
Number.prototype.mod = function(n) {
return ((this % n) + n) % n;
}
Run Code Online (Sandbox Code Playgroud)
使用:
function mod(n, m) {
return ((n % m) + m) % m;
}
Run Code Online (Sandbox Code Playgroud)
见:http://jsperf.com/negative-modulo/2
比原型快〜97%.如果表现当然对你很重要..
Rob*_*ers 24
在%
JavaScript中运算符是求余运算符,而不是模运算符(如何负数的处理方式主要区别):
-1 % 8 // -1, not 7
Sha*_*mal 16
用于返回正结果的"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
Run Code Online (Sandbox Code Playgroud)
而且当然
mod(-13,64) // 51
Run Code Online (Sandbox Code Playgroud)
接受的答案让我有点紧张,因为它重新使用了%运算符.如果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
Run Code Online (Sandbox Code Playgroud)
小智 8
成功实施科学计算或算法不仅可以通过了解特定语言或框架提供的功能,还可以了解其局限性.
计算机是精确的科学仪器,但它们通过操纵离散空间中的实体来工作(屏幕上的像素数量有限,每个数字后面的位数有限,等等)
尽量忽略限制或框架规范,很快你就会发现你的数学公式与你尝试编写的代码之间存在阻抗不匹配.
有时,错误地宣传或理解框架功能或操作员会使情况变得复杂.本文重点介绍模运算符.
问任何C#或JavaScript程序员他们的语言中的模运算符是什么,他们很可能会回答:%(例如百分号).大量文档将%符号称为模运算符.
哇!这是一个微妙但非常危险的错误.在C#和JavaScript中,%运算符实际用于计算当一个操作数除以第二个操作数时剩余的余数(带符号).因此,操作数应正确地称为有符号余数运算符.
乍一看,带符号的余数运算符的功能与模运算符类似.让我们通过将JavaScript返回的结果与Google返回的结果进行比较来进行一些测试.
在Chrome中,打开控制台(按F12并选择控制台选项卡).从左列开始逐个输入.接下来在Google搜索栏中输入相同的表达式.注意结果.它们应该是一样的.
JavaScript Google
5 % 3 2 2
26 % 26 0 0
15 % 12 3 3
Run Code Online (Sandbox Code Playgroud)
我们现在尝试使用负值作为第一个操作数:
惊喜!
-5%3 = 1(根据谷歌)-5%3 = -2(根据JavaScript)
嗯......如果我们看一下JavaScript中的%运算符的定义(......甚至C#或许多其他语言),这实际上不应该是一个惊喜.谷歌计算真正的模数,而这些计算机语言计算签名提醒.
但是,并非所有编程语言/框架都具有相同的%实现.例如,在Python中,%运算符以与Google相同的方式计算真模数.
语言之间的这种行为差异可能会在计算中引入细微的错误,尤其是当您尝试将算法从一种语言移植到另一种语言时!
假设我们需要使用模运算在JavaScript中实现(科学)计算.
由于我们现在明白JavaScript没有真正的模运算符,因此我们可以轻松地将模运算作为函数来实现.
有多种方法可以在JavaScript中实现模数.我将向您展示3种方法.
// Implement modulo by replacing the negative operand
// with an equivalent positive operand that has the same wrap-around effect
function mod(n, p)
{
if ( n < 0 )
n = p - Math.abs(n) % p;
return n % p;
}
// Implement modulo by relying on the fact that the negative remainder
// is always p numbers away from a positive reminder
// Ex: -5 % 3 | -5 = -2 * 3 + 1 and -5 = -1 * 3 + (-2) | -2 + 3 = 1
function mod(n, p)
{
var r = n % p;
return r < 0 ? r + p : r;
}
// Implement modulo by solving n = v * p + r equation
function mod(n, p)
{
return n - p * Math.floor( n / p );
}
Run Code Online (Sandbox Code Playgroud)
借助我们可以使用的更精确的工具,我们现在已准备好处理该(科学)计算并期望每次都能获得正确的结果.
注意:有很多计算使用模运算...如果你想看看如何在实现Caesar Cipher/ROT13代码中使用这些新的模数函数,你可以查看这篇文章.
%
)使用 ES6 Arrow 函数进行简化,并且不会危险地扩展 Number 原型
const mod = (n, m) => (n % m + m) % m;
console.log(mod(-90, 360)); // 270 (Instead of -90)
Run Code Online (Sandbox Code Playgroud)
如果x
是整数并且n
是 2 的幂,则可以使用x & (n - 1)
代替x % n
。
> -13 & (64 - 1)
51
Run Code Online (Sandbox Code Playgroud)