通用的取余运算(包含负数取余)
取余运算,也称为模运算,是数学中的一个操作,用来找出两个数相除后的余数。对于负数的取余,其结果的符号与除数相同。在这个例子中,我们要计算 (-13) 除以 (12) 的余数。
取余运算的公式是:
余数= a−(b×⌊b/a⌋)
其中a是被除数,b是除数,⌊b/a⌋是 a 除以b的向下取整结果。
对于-13取余12,我们首先计算-13除以12的商,然后乘以12,最后用-13减去这个乘积得到余数。
首先计算商:
⌊-13/12⌋ = -2
然后计算乘积:
-2 * 12 = -24
最后计算余数:
-13 - (-24) = -13 + 24 = 11
所以-13取余12等于11。
关于数学:JavaScript%(取模)对负数给出负结果
根据Google计算器,(-13) % 64是51。
根据Javascript(请参阅此JSBin),它是-13。
该如何解决?
相关讨论
Number.prototype.mod = function(n) { return ((this%n)+n)%n; };
相关讨论
使用Number.prototype的速度很慢,因为每次使用原型方法时,您的数字都会包装在Object中。代替这个:
Number.prototype.mod = function(n) { return ((this % n) + n) % n; }
采用:
function mod(n, m) { return ((n % m) + m) % m; }
比使用原型快约97%。
相关讨论
JavaScript中的%运算符是余数运算符,而不是模运算符(主要区别在于如何处理负数):
-1 % 8 // -1, not 7
相关讨论
" 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 // 而且当然 mod(-13,64) // 51
相关讨论
接受的答案让我有些紧张,因为它重复使用了%运算符。如果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 Modulo操作
科学计算或算法的成功实施不仅可以通过了解特定语言或框架提供的功能,而且可以了解其局限性。
计算机是精确的科学仪器,但是它们通过操纵离散空间中的实体来工作(您在屏幕上的像素数量有限,每个数字后面的位数有限,等等)。
尝试忽略限制或框架规范,很快您就会发现数学公式与尝试编写的代码之间存在阻抗不匹配的情况。
模运算符
有时,由于虚假宣传或理解框架功能或运算符而使情况变得复杂。本文重点介绍模运算符。
询问任何C#或JavaScript程序员,他们的语言中的模运算符是什么,他们很有可能会回答:%(例如,百分号)。许多文档将%符号称为模运算符。
哇!这是一个微妙但非常危险的错误。在C#和JavaScript中,%运算符实际上用于计算一个操作数除以第二个操作数时剩余的余数(带符号)。因此,该操作数应正确地称为带符号的余数运算符。
乍看之下,带符号的余数运算符的功能类似于模运算符。让我们将JavaScript返回的结果与Google返回的结果进行比较,以进行一些测试。
在Chrome中,打开控制台(按F12并选择"控制台"选项卡)。从左栏中一一键入计算内容。接下来,在Google搜索栏中键入相同的表达式。注意结果。它们应该是相同的。
JavaScript | ||
---|---|---|
5 % 3 | 2 | 2 |
26 % 26 | 0 | 0 |
15 % 12 | 3 | 3 |
现在,让我们尝试使用负值作为第一个操作数:
惊喜!
-5%3 = 1(根据Google)
-5%3 = -2(根据JavaScript)
好吧……如果我们看看JavaScript(甚至是C#或许多其他语言)中的%运算符定义,这实际上并不令人感到意外。 Google计算真正的模,而这些计算机语言计算带符号的提醒。
但是,并非所有的编程语言/框架都对%具有相同的实现。例如,在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 ); }
相关讨论
有一个NPM软件包可以为您完成工作。您可以使用以下命令进行安装。
npm install just-modulo --save
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
本文作者:jikefan
本文链接:https://www.cnblogs.com/jikefan/articles/18320220
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。