9

I've this PHP function which does not work for negative numbers:

function isOdd($num) 
{
   return $num % 2 == 1; 
}

but it works for positive number.

I have this Perl routine which does the exact same thing and works for negative number also

sub isOdd()
{
  my ($num) = @_;
  return $num % 2 == 1;
}

Did I make any mistake in translating the function ? or is it PHP bug ?

codaddict
  • 445,704
  • 82
  • 492
  • 529
user640527
  • 93
  • 3

1 Answers1

21

In PHP the sign of the result of x % y is the sign of dividend which is x but
in Perl it is the sign of the divisor which is y.

So in PHP the result of $num % 2 can be be either 1, -1 or 0.

So fix your function compare the result with 0:

function isOdd($num) { 
  return $num % 2 != 0; 
}
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • but why? this is fundamental math. Why it changes ? – user640527 Mar 02 '11 at 04:35
  • 3
    @user640527: Its a language design decision. Of the languages I know Perl and Ruby return sign of divisor and C,C++,Java and PHP return sign of dividend. – codaddict Mar 02 '11 at 04:56
  • 1
    +1 (associated documentation) http://www.php.net/manual/en/language.operators.arithmetic.php : "The result of the modulus operator % has the same sign as the dividend — that is, the result of $a % $b will have the same sign as $a." –  Mar 02 '11 at 05:44
  • 1
    Python works like Perl and Ruby in this regard. `5 % 2` and `-5 % 2` both return `1`, while `5 % -2` and `-5 % -2` both return `-1`. **WATCH:** `perl -e '@langs = ( "perl -le ", "ruby -le ", "python -c"); for $dividend ("+5", "-5") {for $divisor ("+2", "-2") {for $lang (@langs) { $cmd = "$lang \047print $dividend % $divisor\047"; print "$cmd\t=> "; system $cmd} print "\n"}}'` – tchrist Mar 04 '11 at 14:24