Skip to content

Deconfuse % and mod behaviours #504

@librasteve

Description

@librasteve

It has been noted that the Raku general modulo operator % and integer modulo operator mod do some unanticipated things.

For example:

Welcome to Rakudo™ v2025.08.

-pi % 1;          #0.8584073464102069
-pi mod 1;        #-0.14159265358979312

#EDIT - I had these results the wrong way round first time - sorry

and

-7.7 % 1.9;       #1.8
-7.7 mod 1.9;     #5.6

for %

the docs say:

multi infix:<%>($x, $y --> Numeric:D)
Modulo operator. Coerces to Numeric first.
Generally the following identity holds:
my ($x, $y) = 1,2;
$x % $y == $x - floor($x / $y) * $y

and Synopsis S03 says:

infix:<%>, modulo

$x % $y
If necessary, coerces non-numeric arguments to an appropriate Numeric type, then calculates the remainder, which is defined as:

$x % $y == $x - floor($x / $y) * $y
If both operands are Ints, the operator returns an Int.

If both operands are of integer or rational type, the operator returns the corresponding Rat value (except when the result does not fit into a Rat, as detailed in S02).

for mod

docs

multi infix:<mod>(Int:D $a, Int:D $b --> Int:D)
Integer modulo operator. Returns the remainder of an integer modulo operation.

S03

infix:<mod>, integer modulo

$x mod $y
Dispatches to the infix:<mod> multi most appropriate to the operand types, returning a value of the same type. Not coercive, so fails on differing types.

This should preserve the identity

$x mod $y == $x - ($x div $y) * $y

so this raises some questions:

  • are these two operators well specified?
  • does the current Rakudo compiler (v6) implement the specification correctly?
  • do the specifications hold water?
  • should we consider changing the behaviour (eg in 6.e)?
  • do we need to improve ROAST?
  • do we need to improve the docs?

I encourage everyone to share their views on these points, mine follow below:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions