@@ -46,6 +46,27 @@ pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
46
46
/// assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
47
47
/// ```
48
48
fn rem_euclid ( & self , v : & Self ) -> Self ;
49
+
50
+ /// Returns both the quotient and remainder from Euclidean division.
51
+ ///
52
+ /// By default, it internally calls both `Euclid::div_euclid` and `Euclid::rem_euclid`,
53
+ /// but it can be overridden in order to implement some optimization.
54
+ ///
55
+ /// # Examples
56
+ ///
57
+ /// ```
58
+ /// # use num_traits::Euclid;
59
+ /// let x = 5u8;
60
+ /// let y = 3u8;
61
+ ///
62
+ /// let div = Euclid::div_euclid(&x, &y);
63
+ /// let rem = Euclid::rem_euclid(&x, &y);
64
+ ///
65
+ /// assert_eq!((div, rem), Euclid::div_rem_euclid(&x, &y));
66
+ /// ```
67
+ fn div_rem_euclid ( & self , v : & Self ) -> ( Self , Self ) {
68
+ ( self . div_euclid ( v) , self . rem_euclid ( v) )
69
+ }
49
70
}
50
71
51
72
macro_rules! euclid_forward_impl {
@@ -174,6 +195,26 @@ pub trait CheckedEuclid: Euclid {
174
195
/// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
175
196
/// division by zero. If any of that happens, `None` is returned.
176
197
fn checked_rem_euclid ( & self , v : & Self ) -> Option < Self > ;
198
+
199
+ /// Returns both the quotient and remainder from checked Euclidean division.
200
+ ///
201
+ /// By default, it internally calls both `CheckedEuclid::checked_div_euclid` and `CheckedEuclid::checked_rem_euclid`,
202
+ /// but it can be overridden in order to implement some optimization.
203
+ /// # Examples
204
+ ///
205
+ /// ```
206
+ /// # use num_traits::CheckedEuclid;
207
+ /// let x = 5u8;
208
+ /// let y = 3u8;
209
+ ///
210
+ /// let div = CheckedEuclid::checked_div_euclid(&x, &y);
211
+ /// let rem = CheckedEuclid::checked_rem_euclid(&x, &y);
212
+ ///
213
+ /// assert_eq!(Some((div.unwrap(), rem.unwrap())), CheckedEuclid::checked_div_rem_euclid(&x, &y));
214
+ /// ```
215
+ fn checked_div_rem_euclid ( & self , v : & Self ) -> Option < ( Self , Self ) > {
216
+ Some ( ( self . checked_div_euclid ( v) ?, self . checked_rem_euclid ( v) ?) )
217
+ }
177
218
}
178
219
179
220
macro_rules! checked_euclid_forward_impl {
@@ -262,8 +303,11 @@ mod tests {
262
303
{
263
304
let x: $t = 10 ;
264
305
let y: $t = 3 ;
265
- assert_eq!( Euclid :: div_euclid( & x, & y) , 3 ) ;
266
- assert_eq!( Euclid :: rem_euclid( & x, & y) , 1 ) ;
306
+ let div = Euclid :: div_euclid( & x, & y) ;
307
+ let rem = Euclid :: rem_euclid( & x, & y) ;
308
+ assert_eq!( div, 3 ) ;
309
+ assert_eq!( rem, 1 ) ;
310
+ assert_eq!( ( div, rem) , Euclid :: div_rem_euclid( & x, & y) ) ;
267
311
}
268
312
) +
269
313
} ;
@@ -284,6 +328,7 @@ mod tests {
284
328
assert_eq!( Euclid :: div_euclid( & -x, & y) , 4 ) ;
285
329
assert_eq!( Euclid :: rem_euclid( & x, & y) , 1 ) ;
286
330
assert_eq!( Euclid :: rem_euclid( & -x, & y) , 2 ) ;
331
+ assert_eq!( ( Euclid :: div_euclid( & x, & y) , Euclid :: rem_euclid( & x, & y) ) , Euclid :: div_rem_euclid( & x, & y) ) ;
287
332
let x: $t = $t:: min_value( ) + 1 ;
288
333
let y: $t = -1 ;
289
334
assert_eq!( Euclid :: div_euclid( & x, & y) , $t:: max_value( ) ) ;
@@ -311,6 +356,7 @@ mod tests {
311
356
<= 46.4 * <$t as crate :: float:: FloatCore >:: epsilon( ) ) ;
312
357
assert!( Euclid :: div_euclid( & -x, & -y) * -y + Euclid :: rem_euclid( & -x, & -y) + x
313
358
<= 46.4 * <$t as crate :: float:: FloatCore >:: epsilon( ) ) ;
359
+ assert_eq!( ( Euclid :: div_euclid( & x, & y) , Euclid :: rem_euclid( & x, & y) ) , Euclid :: div_rem_euclid( & x, & y) ) ;
314
360
}
315
361
) +
316
362
} ;
0 commit comments