develooper Front page | perl.perl5.porters | Postings from February 2008

Modulo operator and floating point numbers

Thread Next
Ken Williams
February 16, 2008 21:22
Modulo operator and floating point numbers
Message ID:

I was reading the p5p summary this week and saw the doc patch for the
modulo operator.  It still didn't seem quite right to me, so I offer
the patch at the end of this message as at least an incremental

 1) It's the "modulo" operator - "modulus" is the name for the second argument.

 2) "not greater than" is better known as "less than or equal to"

 3) "the division remainder of two numbers" sounds like a symmetric
operator or something, which % most certainly isn't.

As soon as I started reading the part of the docs about what happens
with floating point numbers though, I found what it was saying a bit
"troubling."  The documented (and actual) behavior is weird at best,
and likely problematic for anyone who cares what the operator does:

% perl -le '$umax=4294967295; for(-3..3) {$m=$umax+$_; print "4.4 ==
", 4.4 % $m, " (mod $m)"}'
4.4 == 4 (mod 4294967292)
4.4 == 4 (mod 4294967293)
4.4 == 4 (mod 4294967294)
4.4 == 4 (mod 4294967295)
4.4 == 4.4 (mod 4294967296)
4.4 == 4.4 (mod 4294967297)
4.4 == 4.4 (mod 4294967298)

The left argument is coerced to an integer when the right argument is
smallish, but not when it's biggish.


I can think of a few ways to make it more sensible, most of which
would probably also make it less complicated in implementation, but is
it too late to change it?


--- pod/perlop.pod~	2008-02-08 09:33:47.000000000 -0600
+++ pod/perlop.pod	2008-02-16 23:02:27.000000000 -0600
@@ -260,9 +260,11 @@
 Binary "/" divides two numbers.
 X</> X<slash>

-Binary "%" computes the division remainder of two numbers.  Given integer
+Binary "%" is the modulo operator, which computes the division
+remainder of its first argument with respect to its second argument.
+Given integer
 operands C<$a> and C<$b>: If C<$b> is positive, then C<$a % $b> is
-C<$a> minus the largest multiple of C<$b> that is not greater than
+C<$a> minus the largest multiple of C<$b> less than or equal to
 C<$a>.  If C<$b> is negative, then C<$a % $b> is C<$a> minus the
 smallest multiple of C<$b> that is not less than C<$a> (i.e. the
 result will be less than or equal to zero).  If the operands
@@ -273,14 +275,14 @@
 If the absolute value of the right operand (C<abs($b)>) is greater than
 or equal to C<(UV_MAX + 1)>, "%" computes the floating-point remainder
 C<$r> in the equation C<($r = $a - $i*$b)> where C<$i> is a certain
-integer that makes C<$r> should have the same sign as the right operand
+integer that makes C<$r> have the same sign as the right operand
 C<$b> (B<not> as the left operand C<$a> like C function C<fmod()>)
 and the absolute value less than that of C<$b>.
 Note that when C<use integer> is in scope, "%" gives you direct access
-to the modulus operator as implemented by your C compiler.  This
+to the modulo operator as implemented by your C compiler.  This
 operator is not as well defined for negative operands, but it will
 execute faster.
-X<%> X<remainder> X<modulus> X<mod>
+X<%> X<remainder> X<modulo> X<mod>

 Binary "x" is the repetition operator.  In scalar context or if the left
 operand is not enclosed in parentheses, it returns a string consisting

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About