@@ -191,6 +191,24 @@ impl Div<T,T> for T {
191
191
#[cfg(stage2,notest)]
192
192
#[cfg(stage3,notest)]
193
193
impl Quot<T,T> for T {
194
+ /**
195
+ * Returns the integer quotient, truncated towards 0. As this behaviour reflects
196
+ * the underlying machine implementation it is more efficient than `Natural::div`.
197
+ *
198
+ * # Examples
199
+ *
200
+ * ~~~
201
+ * assert!( 8 / 3 == 2);
202
+ * assert!( 8 / -3 == -2);
203
+ * assert!(-8 / 3 == -2);
204
+ * assert!(-8 / -3 == 2);
205
+
206
+ * assert!( 1 / 2 == 0);
207
+ * assert!( 1 / -2 == 0);
208
+ * assert!(-1 / 2 == 0);
209
+ * assert!(-1 / -2 == 0);
210
+ * ~~~
211
+ */
194
212
#[inline(always)]
195
213
fn quot(&self, other: &T) -> T { *self / *other }
196
214
}
@@ -205,6 +223,27 @@ impl Modulo<T,T> for T {
205
223
#[cfg(stage2,notest)]
206
224
#[cfg(stage3,notest)]
207
225
impl Rem<T,T> for T {
226
+ /**
227
+ * Returns the integer remainder after division, satisfying:
228
+ *
229
+ * ~~~
230
+ * assert!((n / d) * d + (n % d) == n)
231
+ * ~~~
232
+ *
233
+ * # Examples
234
+ *
235
+ * ~~~
236
+ * assert!( 8 % 3 == 2);
237
+ * assert!( 8 % -3 == 2);
238
+ * assert!(-8 % 3 == -2);
239
+ * assert!(-8 % -3 == -2);
240
+
241
+ * assert!( 1 % 2 == 1);
242
+ * assert!( 1 % -2 == 1);
243
+ * assert!(-1 % 2 == -1);
244
+ * assert!(-1 % -2 == -1);
245
+ * ~~~
246
+ */
208
247
#[inline(always)]
209
248
fn rem(&self, other: &T) -> T { *self % *other }
210
249
}
@@ -247,6 +286,123 @@ impl Signed for T {
247
286
fn is_negative(&self) -> bool { *self < 0 }
248
287
}
249
288
289
+ impl Natural for T {
290
+ /**
291
+ * Floored integer division
292
+ *
293
+ * # Examples
294
+ *
295
+ * ~~~
296
+ * assert!(( 8).div( 3) == 2);
297
+ * assert!(( 8).div(-3) == -3);
298
+ * assert!((-8).div( 3) == -3);
299
+ * assert!((-8).div(-3) == 2);
300
+ *
301
+ * assert!(( 1).div( 2) == 0);
302
+ * assert!(( 1).div(-2) == -1);
303
+ * assert!((-1).div( 2) == -1);
304
+ * assert!((-1).div(-2) == 0);
305
+ * ~~~
306
+ */
307
+ #[inline(always)]
308
+ fn div(&self, other: T) -> T {
309
+ // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
310
+ // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
311
+ match self.quot_rem(other) {
312
+ (q, r) if (r > 0 && other < 0)
313
+ || (r < 0 && other > 0) => q - 1,
314
+ (q, _) => q,
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Integer modulo, satisfying:
320
+ *
321
+ * ~~~
322
+ * assert!(n.div(d) * d + n.modulo(d) == n)
323
+ * ~~~
324
+ *
325
+ * # Examples
326
+ *
327
+ * ~~~
328
+ * assert!(( 8).modulo( 3) == 2);
329
+ * assert!(( 8).modulo(-3) == -1);
330
+ * assert!((-8).modulo( 3) == 1);
331
+ * assert!((-8).modulo(-3) == -2);
332
+ *
333
+ * assert!(( 1).modulo( 2) == 1);
334
+ * assert!(( 1).modulo(-2) == -1);
335
+ * assert!((-1).modulo( 2) == 1);
336
+ * assert!((-1).modulo(-2) == -1);
337
+ * ~~~
338
+ */
339
+ #[inline(always)]
340
+ fn modulo(&self, other: T) -> T {
341
+ // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
342
+ // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
343
+ match *self % other {
344
+ r if (r > 0 && other < 0)
345
+ || (r < 0 && other > 0) => r + other,
346
+ r => r,
347
+ }
348
+ }
349
+
350
+ /// Calculates `div` and `modulo` simultaneously
351
+ #[inline(always)]
352
+ fn div_mod(&self, other: T) -> (T,T) {
353
+ // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
354
+ // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
355
+ match self.quot_rem(other) {
356
+ (q, r) if (r > 0 && other < 0)
357
+ || (r < 0 && other > 0) => (q - 1, r + other),
358
+ (q, r) => (q, r),
359
+ }
360
+ }
361
+
362
+ /// Calculates `quot` (`\` ) and `rem` (`%`) simultaneously
363
+ #[inline(always)]
364
+ fn quot_rem(&self, other: T) -> (T,T) {
365
+ (*self / other, *self % other)
366
+ }
367
+
368
+ /**
369
+ * Calculates the Greatest Common Divisor (GCD) of the number and `other`
370
+ *
371
+ * The result is always positive
372
+ */
373
+ #[inline(always)]
374
+ fn gcd(&self, other: T) -> T {
375
+ // Use Euclid's algorithm
376
+ let mut m = *self, n = other;
377
+ while m != 0 {
378
+ let temp = m;
379
+ m = n % temp;
380
+ n = temp;
381
+ }
382
+ n.abs()
383
+ }
384
+
385
+ /**
386
+ * Calculates the Lowest Common Multiple (LCM) of the number and `other`
387
+ */
388
+ #[inline(always)]
389
+ fn lcm(&self, other: T) -> T {
390
+ ((*self * other) / self.gcd(other)).abs() // should not have to recaluculate abs
391
+ }
392
+
393
+ /// Returns `true` if the number can be divided by `other` without leaving a remainder
394
+ #[inline(always)]
395
+ fn divisible_by(&self, other: T) -> bool { *self % other == 0 }
396
+
397
+ /// Returns `true` if the number is divisible by `2`
398
+ #[inline(always)]
399
+ fn is_even(&self) -> bool { self.divisible_by(2) }
400
+
401
+ /// Returns `true` if the number is not divisible by `2`
402
+ #[inline(always)]
403
+ fn is_odd(&self) -> bool { !self.is_even() }
404
+ }
405
+
250
406
#[cfg(notest)]
251
407
impl BitOr<T,T> for T {
252
408
#[inline(always)]
@@ -388,6 +544,95 @@ mod tests {
388
544
assert!((-1 as T).is_negative());
389
545
}
390
546
547
+ /**
548
+ * Checks that the division rule holds for:
549
+ *
550
+ * - `n`: numerator (dividend)
551
+ * - `d`: denominator (divisor)
552
+ * - `qr`: quotient and remainder
553
+ */
554
+ #[cfg(test)]
555
+ fn test_division_rule(nd: (T,T), qr: (T,T)) {
556
+ let (n,d) = nd,
557
+ (q,r) = qr;
558
+
559
+ assert_eq!(d * q + r, n);
560
+ }
561
+
562
+ #[test]
563
+ fn test_quot_rem() {
564
+ fn test_nd_qr(nd: (T,T), qr: (T,T)) {
565
+ let (n,d) = nd;
566
+ let separate_quot_rem = (n / d, n % d);
567
+ let combined_quot_rem = n.quot_rem(d);
568
+
569
+ assert_eq!(separate_quot_rem, qr);
570
+ assert_eq!(combined_quot_rem, qr);
571
+
572
+ test_division_rule(nd, separate_quot_rem);
573
+ test_division_rule(nd, combined_quot_rem);
574
+ }
575
+
576
+ test_nd_qr(( 8, 3), ( 2, 2));
577
+ test_nd_qr(( 8, -3), (-2, 2));
578
+ test_nd_qr((-8, 3), (-2, -2));
579
+ test_nd_qr((-8, -3), ( 2, -2));
580
+
581
+ test_nd_qr(( 1, 2), ( 0, 1));
582
+ test_nd_qr(( 1, -2), ( 0, 1));
583
+ test_nd_qr((-1, 2), ( 0, -1));
584
+ test_nd_qr((-1, -2), ( 0, -1));
585
+ }
586
+
587
+ #[test]
588
+ fn test_div_mod() {
589
+ fn test_nd_dm(nd: (T,T), dm: (T,T)) {
590
+ let (n,d) = nd;
591
+ let separate_div_mod = (n.div(d), n.modulo(d));
592
+ let combined_div_mod = n.div_mod(d);
593
+
594
+ assert_eq!(separate_div_mod, dm);
595
+ assert_eq!(combined_div_mod, dm);
596
+
597
+ test_division_rule(nd, separate_div_mod);
598
+ test_division_rule(nd, combined_div_mod);
599
+ }
600
+
601
+ test_nd_dm(( 8, 3), ( 2, 2));
602
+ test_nd_dm(( 8, -3), (-3, -1));
603
+ test_nd_dm((-8, 3), (-3, 1));
604
+ test_nd_dm((-8, -3), ( 2, -2));
605
+
606
+ test_nd_dm(( 1, 2), ( 0, 1));
607
+ test_nd_dm(( 1, -2), (-1, -1));
608
+ test_nd_dm((-1, 2), (-1, 1));
609
+ test_nd_dm((-1, -2), ( 0, -1));
610
+ }
611
+
612
+ #[test]
613
+ fn test_gcd() {
614
+ assert_eq!((10 as T).gcd(2), 2 as T);
615
+ assert_eq!((10 as T).gcd(3), 1 as T);
616
+ assert_eq!((0 as T).gcd(3), 3 as T);
617
+ assert_eq!((3 as T).gcd(3), 3 as T);
618
+ assert_eq!((56 as T).gcd(42), 14 as T);
619
+ assert_eq!((3 as T).gcd(-3), 3 as T);
620
+ assert_eq!((-6 as T).gcd(3), 3 as T);
621
+ assert_eq!((-4 as T).gcd(-2), 2 as T);
622
+ }
623
+
624
+ #[test]
625
+ fn test_lcm() {
626
+ assert_eq!((1 as T).lcm(0), 0 as T);
627
+ assert_eq!((0 as T).lcm(1), 0 as T);
628
+ assert_eq!((1 as T).lcm(1), 1 as T);
629
+ assert_eq!((-1 as T).lcm(1), 1 as T);
630
+ assert_eq!((1 as T).lcm(-1), 1 as T);
631
+ assert_eq!((-1 as T).lcm(-1), 1 as T);
632
+ assert_eq!((8 as T).lcm(9), 72 as T);
633
+ assert_eq!((11 as T).lcm(5), 55 as T);
634
+ }
635
+
391
636
#[test]
392
637
fn test_bitwise_ops() {
393
638
assert_eq!(0b1110 as T, (0b1100 as T).bitor(&(0b1010 as T)));
0 commit comments