typeoneerror
typeoneerror

Reputation: 56948

modulus operand in ruby compared to php

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).

Upvotes: 9

Views: 5647

Answers (4)

Jim Heys
Jim Heys

Reputation: 11

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)

Upvotes: 1

numbers1311407
numbers1311407

Reputation: 34072

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.)

Upvotes: 6

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

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.

Upvotes: 15

Kyle W
Kyle W

Reputation: 3752

According to Wolfram Alpha, 2 is correct.

edit: Seems you should be asking why PHP works that way?

edit2: PHP defines it as the remainder from the devision A/B. Whether you consider it a bug, wrong, or a different way of doing things is up to you, I suppose. Personally, I go for the first 2.

Upvotes: -1

Related Questions