Ruby modulo rules with negative numbers are unclear. In IRB:
-7 % 3 == 2
Should be 1
!
Why?
Because -7/3 is -3 under Ruby's integer division semantics. 3*-3 is -9, so that would leave a remainder of 2.
According to the docs, x modulo y is defined as:
x-y*(x/y).floor
When one of the operands to %
is negative, there’s no clear best answer
for what result to return. Every programming language has its own rules.
The Wikipedia page for Modulo operation has a giant table of how
each programming language has decided to handle this, and there’s no clear
consensus:
$ # 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
Some choose the sign of the left-hand operand, and some the right-hand operand. Others don’t specify. For example, The C Programming Language says:
the sign of the result for % [is] machine-dependent for negative operands
Instead of making a particular choice for how to handle this, C just returns whatever the particular hardware or compiler being used have chosen to implement! This seems to have been standardized in more recent versions of the C programming language standards.
If you want to get a particular version in Ruby, there are two different
methods you could call, modulo
aka %
, and remainder
,
with different behaviour on negative numbers:
$ irb
irb(main):001:0> -7.modulo(3)
=> 2
irb(main):002:0> -7.remainder(3)
=> -1
In other languages that don’t have built-in methods for this, you may end
up using %
twice to get the desired sign.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With