带负数的Ruby modulo 3不直观

Bab*_*aig 5 ruby modulo

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

-7 % 3 == 2  
Run Code Online (Sandbox Code Playgroud)

应该1!为什么?

Pau*_*dge 6

因为-7/3在Ruby的整数除法语义下是-3.3*-3是-9,所以剩下2.

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

x-y*(x/y).floor
Run Code Online (Sandbox Code Playgroud)


and*_*otn 6

当其中一个操作数%为负数时,对于返回的结果没有明确的最佳答案.每种编程语言都有自己的规则.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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

$ irb
irb(main):001:0> -7.modulo(3)
=> 2
irb(main):002:0> -7.remainder(3)
=> -1
Run Code Online (Sandbox Code Playgroud)

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