You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0000-euclidean-modulo.md
+21-3Lines changed: 21 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -24,14 +24,14 @@ The behaviour of division and modulo, as implemented by Rust's (truncated) divis
24
24
(-8/3, -8%3) // (-2, -2)
25
25
((-8).div_euc(3), (-8).mod_euc(3)) // (-3, 1)
26
26
```
27
-
Euclidean division & modulo for integers will be achieved using the `div_euc` and `mod_euc` methods. The `%` operator has identical behaviour to `mod_euc` for unsigned integers. However, when using signed integers, you should be careful to consider the behaviour you want: often Euclidean modulo will be more appropriate.
27
+
Euclidean division & modulo for integers and floating-point numbers will be achieved using the `div_euc` and `mod_euc` methods. The `%` operator has identical behaviour to `mod_euc` for unsigned integers. However, when using signed integers or floating-point numbers, you should be careful to consider the behaviour you want: often Euclidean modulo will be more appropriate.
It is important to have both division and modulo methods, as the two operations are intrinsically linked[[8]](https://en.wikipedia.org/wiki/Modulo_operation), though it is often the modulo operator that is specifically requested.
33
33
34
-
A complete implementation of Euclidean modulo would involve adding 8 methods to the integer primitives in `libcore/num/mod.rs`:
34
+
A complete implementation of Euclidean modulo would involve adding 8 methods to the integer primitives in `libcore/num/mod.rs` and 2 methods to the floating-point primitives in `libcore/num` and `libstd`:
And on `f64` (analagous to the `f32` implementation):
70
+
```rust
71
+
fndiv_euc(self, rhs:f64) ->f64 {
72
+
letq= (self/rhs).trunc();
73
+
ifself%rhs<0.0 {
74
+
returnifrhs>0.0 { q-1.0 } else { q+1.0 }
75
+
}
76
+
q
77
+
}
78
+
79
+
fnmod_euc(self, rhs:f64) ->f64 {
80
+
letr=self%rhs;
81
+
ifr<0.0 {
82
+
returnifrhs>0.0 { r+rhs } else { r-rhs }
83
+
}
84
+
r
85
+
}
86
+
```
69
87
70
88
The unsigned implementations of these methods are trivial.
71
89
The `checked_*`, `overflowing_*` and `wrapping_*` methods would operate analogously to their non-Euclidean `*_div` and `*_rem` counterparts that already exist. The edge cases are identical.
@@ -91,4 +109,4 @@ This functionality could instead reside in a separate crate, such as `num` (floo
91
109
# Unresolved questions
92
110
[unresolved]: #unresolved-questions
93
111
94
-
- Is it worth implementing `div_euc` and `mod_euc` for floating-point numbers? While it makes sense for completeness, it may be too rare a use case to be worth extending the core library to include.
0 commit comments