我正在寻找一个简单的解释Ruby的模操作数是如何工作的,为什么,在Ruby
puts 4 % 3 # 1
puts -4 % 3 # 2 <--why?
puts -4 % -3 # -1
但是在PHP中:
<?php
echo 4 % 3; # 1
echo -4 % 3; # -1
echo -4 % -3; # -1
在我看来- 4% 3实际上是8% 3(8是4和-4的差)
它们都可以被认为是正确的,这取决于您的定义。如果是a % n == r
,那么它应该满足:
a == q*n + r
where q == a / n
.
r
是阳性还是阴性由q
的值决定。在你的例子中,
-4 == -1*3 + (-1) // PHP
-4 == -2*3 + 2 // Ruby
换句话说,%
的定义取决于/
的定义。
参见此处的表格:http://en.wikipedia.org/wiki/Modulus_operator#Remainder_calculation_for_the_modulo_operation。您将看到,这在不同的编程语言之间有很大的不同。
下面是Matz和David Flanagan所著的《the Ruby Programming Language》中关于这个主题的一个片段。
当一个(但不是两个)操作数为负时,Ruby执行整数除法和取模操作不同于C、c++和Java可以(但与Python和Tcl语言相同)。考虑商-7/3。Ruby趋向于负无穷返回3。C和相关的语言都趋向于0返回2。在Ruby中,-a/b等于a/-b,但my不等于-(a/b)。
Ruby对模块操作的定义也不同于C语言和Java。在Ruby中,-7%3等于2。在C和Java中,结果是-1代替。结果的大小不同,因为商不同。但结果的标志也不同。在Ruby中,符号结果总是第二个操作数的符号。在C和在Java中,结果的符号总是第一个操作数的符号。(Ruby的余数方法的行为类似于C的模运算符)
这实际上归结为该语言的整型转换/舍入的实现。因为实际的方程是:
a - (n * int(a/n))
是方程的int(a/n)
部分不同。如果a == -4
和n == 3
, PHP将返回-1,而Ruby将生成-2。现在,Ruby中的公式看起来像这样:
-4 - (3 * -2)
和PHP中的
-4 - (3 * -1)
根据Wolfram Alpha, 2是正确的。
似乎你应该问为什么PHP是这样工作的?edit2: PHP将其定义为部门A/B的余数。我想,你是否认为这是一个错误,或者是一种不同的做事方式,这取决于你。