-1%7的结果在javascript(-1)和python(6)中不同

-1%7的结果在javascript(-1)和python(6)中不同,javascript,python,haskell,Javascript,Python,Haskell,JavaScript中的表达式-1%7给了我-1作为结果。而在Python和Haskell中,我发现结果是6 有人能解释为什么两者都有不同的行为吗?哪一个是正确的?两个都是正确的。一些语言返回正模数,而另一些语言保留其符号 您可以简单地将模数添加到变量中以获得一个正数,或者在执行模数运算之前检查该数字是正数还是负数,并在两者之间切换后更正结果 要在这两者之间转换a%b的伪代码: 在-1%7==-1的语言中,这样做是为了得到一个正数: ((a%b)+b) % b 在-1%7==6的语言中,您可

JavaScript中的表达式
-1%7
给了我
-1
作为结果。而在Python和Haskell中,我发现结果是
6


有人能解释为什么两者都有不同的行为吗?哪一个是正确的?

两个都是正确的。一些语言返回正模数,而另一些语言保留其符号

您可以简单地将模数添加到变量中以获得一个正数,或者在执行模数运算之前检查该数字是正数还是负数,并在两者之间切换后更正结果


要在这两者之间转换
a%b
的伪代码:

-1%7==-1
的语言中,这样做是为了得到一个正数:

((a%b)+b) % b
-1%7==6
的语言中,您可以这样做以获得签名版本:

if a < 0:
  return (a%b)-b
else:
  return a%b
如果a<0:
退货(a%b)-b
其他:
返回%b

两者都是正确的,它们只是在处理负数操作数时使用了不同的约定。对于正数,约定一致,但对于负数,约定不一致。在Python中,
a%b
始终与
b
具有相同的符号

在下面的内容中,我将使用Python表示法,其中
/
用于整数除法

q,r=a//b,a%b
然后

a==q*b+r
在任何语言中都必须为真(假设
a
b
为整数,
b
不等于零)。因此,余数的处理方式必须与整数除法的约定一致。在Python中,整数除法是地板除法,即结果向负无穷大舍入。在其他一些语言中,取而代之的是向零舍入。在某些语言中,CPU制造商决定实现的任何约定都可以实现,因此在不同硬件上运行相同的代码可以得到不同的结果。正如你所能想象的那样,这可能有点烦人

两者都是正确的

若要完成其他答案,还可以考虑Python中的函数:


取两个(非复数)数作为参数,使用整数除法时返回一对由其商和余数组成的数。对于混合操作数类型,二进制算术运算符的规则适用。对于整数,结果与
(a//b,a%b)
相同。对于浮点数,结果是
(q,a%b)
,其中q通常是
数学下限(a/b)
,但可能小于1。在任何情况下,
q*b+a%b
与a非常接近,如果
a%b
为非零,它与b具有相同的符号,
0我将给出一个稍微不同的答案。正如其他人所说,函数可以执行您定义它们的任何操作,并且
m-x=-x
mod
m
。作为开场白,我将注意到Haskell有两个“mod”函数,
mod
rem
,它们在这方面有所不同。您可以提出一个例子,说明
mod
one在数学上更可取。
rem
one对应于x86处理器上的处理器。事实上,还有第三种,欧几里得的,它可能比雷蒙德·布特在年所描述的更好。第三种形式总是返回正模。(事实上,至少还有两种选择可以选择。)

因此,Javascript的定义是您从大多数机器
mod
操作码中得到的。从这个意义上讲,这可能更可取,因为这将使其更有效地实施。从数学上讲,Haskell和Python的定义优于Javascript。还有第三个定义可能稍微好一点


欧几里德和Haskell/Python定义都具有的一个关键属性是
xmod m=ymod m
相当于Javascript定义中缺少的
x=y
mod
m
。您可以通过在Javascript中计算
6%7
进行验证。

在Javascript和Python中,
%
代表不同的运算符

在JavaScript中,
%
代表操作符。文档已经指出了余数和模运算之间的区别:

余数运算符返回一个操作数除以第二个操作数时剩余的余数。它总是以股息的符号,而不是除数。它使用内置的模函数生成结果,即var1除以var2的整数余数-例如-var1模var2。有人建议在未来版本的ECMAScript中使用实际的模运算符,不同之处在于模运算符结果将采用除数的符号,而不是股息。

(我强调)

与此相反:在Python中,
%
代表操作符。该文件还对该标志进行了说明:

%
(模)运算符从第一个参数除以第二个参数得到余数。数值参数首先转换为通用类型。零对参数引发ZeroDivisionError异常。[…]模运算符总是产生一个与其第二个操作数(或零)符号相同的结果。;结果的绝对值严格小于第二个操作数的绝对值[2]


(我强调)

有关python,请参阅,以获取有关某些语言中不同行为的更多信息。这些代码片段都不正确。。。第一个应该是
((a%b)+b)%b
(或者
如果a<0:return(a%b)+b如果你更喜欢条件而不是模数,则返回a%b
),第二个
如果a<0:return(a%b)-b否则:返回a%b
@DanielWagner很好,我已经习惯了不必担心溢出。第二个相反,感谢您提到Python允许浮点操作数
>>> divmod(-1, 7)
(-1, 6)