From:

Date:

February 16, 2008 21:22Subject:

Modulo operator and floating point numbersMessage ID:

6a7ee8cc0802162122r4e59b93boee18b1f045b8954d@mail.gmail.comHi, 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 improvement: 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. Eek? 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? -Ken ======================= --- 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

**Modulo operator and floating point numbers**by Ken Williams- Re: Modulo operator and floating point numbers by Rafael Garcia-Suarez
- Re: Modulo operator and floating point numbers by Zefram

nntp.perl.org: Perl Programming lists via nntp and http.

Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About