# (Mathematical) modulo operator

**URL:** <https://internals.rust-lang.org/t/mathematical-modulo-operator/5952>\
**Category:** language design\
**Created:** [September 20, 2017, 7:07pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952 "2017-09-20T19:07:08Z")\
**Posts on this page:** 10\
**Page:** 2

<div class="post-metadata">

**Author:** ![ExpHP](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exphp/32/6208_2.png) [@ExpHP](https://internals.rust-lang.org/u/ExpHP)\
**Post date:** [October 5, 2017, 11:20pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/21 "2017-10-05T23:20:57Z")

</div>

> [@varkor](#):
>
> Unless there’s a good reason not to, I would lean towards flooring modulo which has the advantages that: (a) it requires one fewer (abs) operations; (b) can easily be used to implement Euclidean modulo if really needed.

I don't buy these arguments as they can be easily turned around depending on how they are implemented. One could say [euclidean division uses two fewer sign comparisons](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf) (compare `modE` and `modF` on page 5). One would have to benchmark various implementations of both algorithms to find the global minimum.

---

<div class="post-metadata">

**Author:** ![fanzier](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/fanzier/32/2740_2.png) [@fanzier](https://internals.rust-lang.org/u/fanzier)\
**Post date:** [October 7, 2017, 3:35pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/22 "2017-10-07T15:35:50Z")

</div>

Thanks for writing this up!

Ad 1: I don’t think it’s useful to have both flooring and Euclidean division available as functions, at least not in this verbose form. Who wants to write `5.mod_round(3, num::DivisionMode::Euclidean)` instead of, say, `5.mod_e(3)`? I think short names are important here given that the worst choice (truncating mod) is one character `%`.

Ad 2: So a single division/modulo function is definitely better. I have a slight preference for Euclidean division (it’s more well-behaved according to the paper linked in your first post) but if flooring division is faster, then I’m fine with sacrificing the regularity of Euclidean division for the performance of flooring division. But I agree with @ExpHP that there seems to be no evidence so far supporting the statement that flooring division is faster.

Small proposal: I also think it might be useful to add a `fn divMod(self, rhs: Self) -> (Self, Self)` function, returning the division and modulo result, similarly to Haskell. Such a function could also be added later, of course, if you want to keep the RFC minimal.

---

<div class="post-metadata">

**Author:** ![varkor](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/varkor/32/2738_2.png) [@varkor](https://internals.rust-lang.org/u/varkor)\
**Post date:** [October 9, 2017, 2:12pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/23 "2017-10-09T14:12:43Z")

</div>

> [@ExpHP](#):
>
> One would have to benchmark various implementations of both algorithms to find the global minimum.

You're right; I should have benchmarked first: using the algorithms in the paper gives functions with essentially identical performance (for all three rounding variants, and for both division and modulo).

> [@fanzier](#):
>
> Small proposal: I also think it might be useful to add a fn divMod(self, rhs: Self) -\> (Self, Self) function, returning the division and modulo result, similarly to Haskell.

I think it would be better to address this in a future proposal, as it does not appear strictly related to the issue this RFC focuses on.

The preference expressed at least here seems to be for Euclidean modulo, so I'll focus on that in the RFC (hopefully to follow shortly). Thanks for all your feedback so far!

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 9, 2017, 6:07pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/24 "2017-10-09T18:07:49Z")

</div>

The biggest opposition I expect to the RFC is why it needs to be in core. The standard library’s support for mathy stuff in general is poor, mostly on purpose. So this will need a clear benefit to being in core instead of, say, the num crate.

---

<div class="post-metadata">

**Author:** ![leonardo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/leonardo/32/1344_2.png) [@leonardo](https://internals.rust-lang.org/u/leonardo)\
**Post date:** [October 9, 2017, 6:42pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/25 "2017-10-09T18:42:01Z")

</div>

> [@scottmcm](#):
>
> So this will need a clear benefit to being in core instead of, say, the num crate.

In my opinion the main benefit of having this in the Prelude or std library is to help new programmers be aware of the pitfalls of the built-in operators.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [October 9, 2017, 8:36pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/26 "2017-10-09T20:36:01Z")

</div>

> [@scottmcm](#):
>
> So this will need a clear benefit to being in core instead of, say, the num crate.

[`Integer`](https://docs.rs/num-integer/0.1.35/num_integer/trait.Integer.html) already provides flooring methods. I expect it would be simple to add Euclidean methods too, if someone would like to send a PR.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 9, 2017, 9:17pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/27 "2017-10-09T21:17:35Z")

</div>

With the `div_rem` and `div_mod_floor` functions too! 💖

---

<div class="post-metadata">

**Author:** ![varkor](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/varkor/32/2738_2.png) [@varkor](https://internals.rust-lang.org/u/varkor)\
**Post date:** [October 9, 2017, 10:39pm UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/28 "2017-10-09T22:39:28Z")

</div>

You can now find the [RFC here](https://github.com/rust-lang/rfcs/pull/2169)! Thank you for all your constructive comments beforehand — there are probably still details to work out, but the ideas feel a lot stronger now.

> [@cuviper](#):
>
> I expect it would be simple to add Euclidean methods too, if someone would like to send a PR.

That could be a good stop-gap! I do think it is useful enough to warrant a core implementation, but as an RFC can take a while to progress, a `num` PR could be a way to provide the functionality earlier.

---

<div class="post-metadata">

**Author:** ![varkor](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/varkor/32/2738_2.png) [@varkor](https://internals.rust-lang.org/u/varkor)\
**Post date:** [April 18, 2018, 12:35am UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/29 "2018-04-18T00:35:04Z")

</div>

As a final follow up to the discussion here, (unstable) [Euclidean modulo methods have now been added](https://github.com/rust-lang/rust/pull/49389) to the standard library: thanks @fanzier for implementing the RFC!

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:29am UTC](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952/30 "2019-03-25T08:29:01Z")

</div>

Closed on March 25, 2019, 8:29am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/mathematical-modulo-operator/5952.md?page=1)
