Hi,

UPDATE: I've now filed a bug report about this.

I've been chewing on this over the last couple of days, and it doesn't look right to me.
It's an issue that arises only when NV-precision is greater than IV-precision.
So, if ivsize is 8 bytes, then in order to experience the issue, you'll generally need to use a quadmath build (nvtype of __float28, NV-precision of 113 bits).
With such a perl, I get:
C:\_32>perl -wle "$m = (2**113) - 1; $n = 2; print $m % $n;" 0
In contrast, POSIX::fmod returns "1" for the same operation.
C:\_32>perl -MPOSIX -wle "$m = (2**113) - 1; $n = 2; print fmod($m, $n +);" 1
Here's the section of perlop documentation that I'm looking at:
Binary "%" is the modulo operator, which computes the division remaind +er of its first argument with respect to its second argument. Given integ +er operands $m and $n: If $n is positive, then "$m % $n" is $m minus the largest multiple of $n less than or equal to $m. If $n is negative, th +en "$m % $n" is $m minus the smallest multiple of $n that is not less tha +n $m (that is, the result will be less than or equal to zero). If the operands $m and $n are floating point values and the absolute value of $n (that is "abs($n)") is less than "(UV_MAX + 1)", only the integer portion of $m and $n will be used in the operation (Note: here "UV_MAX +" means the maximum of the unsigned integer type). If the absolute value of the right operand ("abs($n)") is greater than or equal to "(UV_MAX + 1)", "%" computes the floating-point remainder $r in the equation "($r = $m - $i*$n)" where $i is a certain integer that makes +$r have the same sign as the right operand $n (not as the left operand $m like C function "fmod()") and the absolute value less than that of $n. Note that when "use integer" is in scope, "%" gives you direct access +to the modulo operator as implemented by your C compiler. This operator i +s not as well defined for negative operands, but it will execute faster.
AFAICT, the parts of that documentation that are pertinent to my given example are:
If $n is positive, then "$m % $n" is $m minus the largest multiple of +$n less than or equal to $m. .... If the operands $m and $n are floating point values and the absolute v +alue of $n (that is "abs($n)") is less than "(UV_MAX + 1)", only the integer portion of $m and $n will be used in the operation (Note: here "UV_MAX +" means the maximum of the unsigned integer type)
And to me that implies that the correct calculation for the given example is to do:
C:\_32>perl -wle "$r = 10384593717069655257060992658440191.0 - (519229 +6858534827628530496329220095.0 * 2); print $r;" 1
This agrees with the value produced by POSIX::fmod(), but disagrees with the value produced by the "%" operator.
Do we agree that perl is buggy here ?

If you have a perl with ivsize of 4, you can also demonstrate the same issue.
With ivsize of 4, NV-precision of 113 bits:
C:\_32>perl -wle "$m = (2**113) - 1; $n = 2; print $m % $n;" 0 C:\_32>perl -MPOSIX -wle "$m = (2**113) - 1; $n = 2; print fmod($m, $n +);" 1
With ivsize of 4, NV-precision of 64 bits (long double):
C:\>perl -wle "$m = (2**64) - 1; $n = 2; print $m % $n;" 0 C:\>perl -MPOSIX -wle "$m = (2**64) - 1; $n = 2; print fmod($m, $n);" 1
And now to really muddy the waters !! One might be expecting the trend to continue when ivsize is 4, and NV-precision is 53-bits .... but not so:
C:\_32>perl -wle "$m = (2**53) - 1; $n = 2; print $m % $n;" 1 C:\_32>perl -MPOSIX -wle "$m = (2**53) - 1; $n = 2; print fmod($m, $n) +;" 1
This time the "%" operator decides to act in accordance with (my reading of) the perlop documentation.

Cheers,
Rob

In reply to The "%" operator and its documentation. by syphilis

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.