带负数的Ruby modulo 3不直观

具有负数的Ruby模数规则尚不清楚。 在IRB:

-7 % 3 == 2 

应该是1 ! 为什么?

%一个操作数为负数时,对于返回的结果没有明确的最佳答案。 每种编程语言都有自己的规则。 Modulo操作的维基百科页面有一个巨大的表格,列出了每种编程语言如何决定处理这个问题,并且没有明确的共识:

 $ # Modulus sign is: $ $ curl 'http://en.wikipedia.org/w/index.php?title=Modulo_operation&action=edit&section=1' \ | egrep -o 'Divisor|Dividend|Always positive|Closest to zero|Not defined|Implementation defined' \ | sort | uniq -c | sort -nr 67 Dividend 42 Divisor 7 Always positive 4 Closest to zero 2 Not defined 2 Implementation defined 

有些选择左手操作数的符号,有些选择右手操作数。 其他人没有说明。 例如, C编程语言说:

%[是]与负操作数相关的结果符号

C只返回正在使用的特定硬件或编译器选择实现的任何内容,而不是如何处理它的特定选择! 这似乎已在更新版本的C编程语言标准中标准化。

如果你想在Ruby中获得特定版本,你可以调用两种不同的方法, modulo aka %remainder ,在负数上有不同的行为:

 $ irb irb(main):001:0> -7.modulo(3) => 2 irb(main):002:0> -7.remainder(3) => -1 

在其他没有内置方法的语言中,您最终可能会使用%两次来获得所需的符号。

因为-7 / 3在Ruby的整数除法语义下是-3。 3 * -3是-9,所以留下2的余数。

根据文档 ,x modulo y定义为:

 xy*(x/y).floor