带负数的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§ion=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