JavaScript中的表达式-1 % 7
给我的结果是-1
。而在Python和Haskell中,我发现结果是6
。
谁能解释为什么两者都有不同的行为?哪一个是正确的?
发布于 2016-12-20 10:37:05
我将给出一个稍微不同的答案。正如其他人所说,函数可以做您定义的任何事情,并且m - x = -x
mod m
。作为前奏,我会注意到Haskell有两个"mod“函数,mod
和rem
,这两个函数在这方面是不同的。你可以证明,从数学上讲,mod
更可取。rem
one对应于您在x86处理器上获得的内容。事实上,还有第三种,欧几里得的,它可能更好,正如Raymond Boute在The Euclidean Definitions of the Functions Div and Mod中所描述的那样。第三种形式总是返回一个正的模数。(事实上,至少还有两个其他选择可以选择。)
所以,Javascript的定义是你从大多数机器mod
操作码中得到的。从这个意义上说,这可能是更可取的,因为这将使其更有效地实现。从数学上讲,Haskell和Python的定义比Javascript的定义更好,还有第三个定义可能更好一些。
欧几里得和Haskell/Python定义都拥有的一个关键属性是x mod m = y mod m
等同于Javascript的定义所缺少的x = y
mod m
。您可以通过在Javascript中计算6 % 7
来验证。
发布于 2016-12-20 09:47:27
两者都是正确的。一些语言返回正的模数,而另一些语言则保留符号。
您可以简单地将模加到您的变量中以获得正数,或者在执行模运算之前检查该数是正数还是负数,并在执行模运算后更正结果以在两者之间切换。
用于在两者之间转换a%b
的伪代码:
在-1%7 == -1
语言中,你这样做是为了得到一个正数:
((a%b)+b) % b
在一种-1%7 == 6
语言中,你可以这样做来获得签名版本:
if a < 0:
return (a%b)-b
else:
return a%b
发布于 2016-12-20 09:56:36
两者都是正确的,它们只是在处理负操作数时使用了不同的约定。对于正数,约定是一致的,但对于负数,则不是这样。在Python中,a % b
始终与b
具有相同的符号。
在下面的内容中,我将使用Python表示法,其中//
用于整数除法。
让
q, r = a // b, a % b
然后
a == q * b + r
在任何语言中,必须为真(假设a
和b
为整数,且b
不等于零)。因此,处理余数的方式必须与用于整数除法的约定一致。在Python中,整数除法是底除法,即结果舍入到负无穷大。在其他一些语言中,取而代之的是舍入为零。在某些语言中,您会得到CPU制造商决定实现的任何约定,因此相同的代码在不同的硬件上运行可能会产生不同的结果。正如您可以想象的那样,这可能有点烦人。:)
https://stackoverflow.com/questions/41239190
复制相似问题