Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

modulus operand in ruby compared to php

Tags:

php

ruby

I'm looking for a simple explanation for how Ruby's modulo operand works and why, in Ruby

puts  4 % 3   # 1
puts -4 % 3   # 2 <--why?
puts -4 % -3  # -1 

but in PHP:

<?php

echo  4 % 3;  #  1
echo -4 % 3;  # -1
echo -4 % -3; # -1

Looks to me like -4 % 3 is actally 8 % 3 (8 being the difference between 4 and -4).

like image 725
typeoneerror Avatar asked Sep 12 '11 23:09

typeoneerror


3 Answers

They can both be considered correct, depending on your definition. If a % n == r, then it should hold that:

a == q*n + r

where q == a / n.

Whether r is positive or negative is determined by the value of q. So in your example, either of:

-4 == -1*3 + (-1)   // PHP
-4 == -2*3 + 2      // Ruby

To put it another way, the definition of % depends on the definition of /.

See also the table here: http://en.wikipedia.org/wiki/Modulus_operator#Remainder_calculation_for_the_modulo_operation. You'll see that this varies substantially between various programming languages.

like image 182
Oliver Charlesworth Avatar answered Nov 15 '22 20:11

Oliver Charlesworth


Here's a snippet on the topic from The Ruby Programming Language, by Matz and David Flanagan.

When one (but not both) of the operands is negative, Ruby performs the integer division and modulo operations differently than languages like C, C++, and Java do (but the same as the languages Python and Tcl). Consider the quotient -7/3. Ruby rounds toward negative infinity and returns -3. C and related languages round toward zero instead and return -2. In Ruby, -a/b equals a/-b but my not equal -(a/b).

Ruby's definition of the module operation also differs from that of C and Java. In Ruby, -7%3 is 2. In C and Java, the result is -1 instead. The magnitude of the result differs, because the quotient differed. But the sign of the result differs, too. In Ruby, the sign of the result is always the sign of the second operand. In C and Java, the sign of the result is always the sign of the first operand. (Ruby's remainder method behaves like the C modulo operator.)

like image 26
numbers1311407 Avatar answered Nov 15 '22 18:11

numbers1311407


It actually boils down to the implementation of the language's integer casting/rounding. Since the actual equation is:

a - (n * int(a/n))

It is the int(a/n) portion of the equation that differs. If a == -4 and n == 3, PHP will return -1, while Ruby will produce -2. Now the equation looks like this in Ruby:

-4 - (3 * -2)

and this in PHP

-4 - (3 * -1)
like image 34
Jim Heys Avatar answered Nov 15 '22 20:11

Jim Heys