integer.rs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. //! Integer trait and functions.
  11. use {Num, Signed};
  12. pub trait Integer: Num + PartialOrd
  13. + Div<Self, Self>
  14. + Rem<Self, Self> {
  15. /// Floored integer division.
  16. ///
  17. /// # Examples
  18. ///
  19. /// ~~~
  20. /// # use num::Integer;
  21. /// assert!(( 8i).div_floor(& 3) == 2);
  22. /// assert!(( 8i).div_floor(&-3) == -3);
  23. /// assert!((-8i).div_floor(& 3) == -3);
  24. /// assert!((-8i).div_floor(&-3) == 2);
  25. ///
  26. /// assert!(( 1i).div_floor(& 2) == 0);
  27. /// assert!(( 1i).div_floor(&-2) == -1);
  28. /// assert!((-1i).div_floor(& 2) == -1);
  29. /// assert!((-1i).div_floor(&-2) == 0);
  30. /// ~~~
  31. fn div_floor(&self, other: &Self) -> Self;
  32. /// Floored integer modulo, satisfying:
  33. ///
  34. /// ~~~
  35. /// # use num::Integer;
  36. /// # let n = 1i; let d = 1i;
  37. /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
  38. /// ~~~
  39. ///
  40. /// # Examples
  41. ///
  42. /// ~~~
  43. /// # use num::Integer;
  44. /// assert!(( 8i).mod_floor(& 3) == 2);
  45. /// assert!(( 8i).mod_floor(&-3) == -1);
  46. /// assert!((-8i).mod_floor(& 3) == 1);
  47. /// assert!((-8i).mod_floor(&-3) == -2);
  48. ///
  49. /// assert!(( 1i).mod_floor(& 2) == 1);
  50. /// assert!(( 1i).mod_floor(&-2) == -1);
  51. /// assert!((-1i).mod_floor(& 2) == 1);
  52. /// assert!((-1i).mod_floor(&-2) == -1);
  53. /// ~~~
  54. fn mod_floor(&self, other: &Self) -> Self;
  55. /// Greatest Common Divisor (GCD).
  56. ///
  57. /// # Examples
  58. ///
  59. /// ~~~
  60. /// # use num::Integer;
  61. /// assert_eq!(6i.gcd(&8), 2);
  62. /// assert_eq!(7i.gcd(&3), 1);
  63. /// ~~~
  64. fn gcd(&self, other: &Self) -> Self;
  65. /// Lowest Common Multiple (LCM).
  66. ///
  67. /// # Examples
  68. ///
  69. /// ~~~
  70. /// # use num::Integer;
  71. /// assert_eq!(7i.lcm(&3), 21);
  72. /// assert_eq!(2i.lcm(&4), 4);
  73. /// ~~~
  74. fn lcm(&self, other: &Self) -> Self;
  75. /// Deprecated, use `is_multiple_of` instead.
  76. #[deprecated = "function renamed to `is_multiple_of`"]
  77. fn divides(&self, other: &Self) -> bool;
  78. /// Returns `true` if `other` is a multiple of `self`.
  79. ///
  80. /// # Examples
  81. ///
  82. /// ~~~
  83. /// # use num::Integer;
  84. /// assert_eq!(9i.is_multiple_of(&3), true);
  85. /// assert_eq!(3i.is_multiple_of(&9), false);
  86. /// ~~~
  87. fn is_multiple_of(&self, other: &Self) -> bool;
  88. /// Returns `true` if the number is even.
  89. ///
  90. /// # Examples
  91. ///
  92. /// ~~~
  93. /// # use num::Integer;
  94. /// assert_eq!(3i.is_even(), false);
  95. /// assert_eq!(4i.is_even(), true);
  96. /// ~~~
  97. fn is_even(&self) -> bool;
  98. /// Returns `true` if the number is odd.
  99. ///
  100. /// # Examples
  101. ///
  102. /// ~~~
  103. /// # use num::Integer;
  104. /// assert_eq!(3i.is_odd(), true);
  105. /// assert_eq!(4i.is_odd(), false);
  106. /// ~~~
  107. fn is_odd(&self) -> bool;
  108. /// Simultaneous truncated integer division and modulus.
  109. /// Returns `(quotient, remainder)`.
  110. ///
  111. /// # Examples
  112. ///
  113. /// ~~~
  114. /// # use num::Integer;
  115. /// assert_eq!(( 8i).div_rem( &3), ( 2, 2));
  116. /// assert_eq!(( 8i).div_rem(&-3), (-2, 2));
  117. /// assert_eq!((-8i).div_rem( &3), (-2, -2));
  118. /// assert_eq!((-8i).div_rem(&-3), ( 2, -2));
  119. ///
  120. /// assert_eq!(( 1i).div_rem( &2), ( 0, 1));
  121. /// assert_eq!(( 1i).div_rem(&-2), ( 0, 1));
  122. /// assert_eq!((-1i).div_rem( &2), ( 0, -1));
  123. /// assert_eq!((-1i).div_rem(&-2), ( 0, -1));
  124. /// ~~~
  125. #[inline]
  126. fn div_rem(&self, other: &Self) -> (Self, Self);
  127. /// Simultaneous floored integer division and modulus.
  128. /// Returns `(quotient, remainder)`.
  129. ///
  130. /// # Examples
  131. ///
  132. /// ~~~
  133. /// # use num::Integer;
  134. /// assert_eq!(( 8i).div_mod_floor( &3), ( 2, 2));
  135. /// assert_eq!(( 8i).div_mod_floor(&-3), (-3, -1));
  136. /// assert_eq!((-8i).div_mod_floor( &3), (-3, 1));
  137. /// assert_eq!((-8i).div_mod_floor(&-3), ( 2, -2));
  138. ///
  139. /// assert_eq!(( 1i).div_mod_floor( &2), ( 0, 1));
  140. /// assert_eq!(( 1i).div_mod_floor(&-2), (-1, -1));
  141. /// assert_eq!((-1i).div_mod_floor( &2), (-1, 1));
  142. /// assert_eq!((-1i).div_mod_floor(&-2), ( 0, -1));
  143. /// ~~~
  144. fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
  145. (self.div_floor(other), self.mod_floor(other))
  146. }
  147. }
  148. /// Simultaneous integer division and modulus
  149. #[inline] pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) { x.div_rem(&y) }
  150. /// Floored integer division
  151. #[inline] pub fn div_floor<T: Integer>(x: T, y: T) -> T { x.div_floor(&y) }
  152. /// Floored integer modulus
  153. #[inline] pub fn mod_floor<T: Integer>(x: T, y: T) -> T { x.mod_floor(&y) }
  154. /// Simultaneous floored integer division and modulus
  155. #[inline] pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) { x.div_mod_floor(&y) }
  156. /// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
  157. /// result is always positive.
  158. #[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
  159. /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
  160. #[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
  161. macro_rules! impl_integer_for_int {
  162. ($T:ty, $test_mod:ident) => (
  163. impl Integer for $T {
  164. /// Floored integer division
  165. #[inline]
  166. fn div_floor(&self, other: &$T) -> $T {
  167. // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
  168. // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
  169. match self.div_rem(other) {
  170. (d, r) if (r > 0 && *other < 0)
  171. || (r < 0 && *other > 0) => d - 1,
  172. (d, _) => d,
  173. }
  174. }
  175. /// Floored integer modulo
  176. #[inline]
  177. fn mod_floor(&self, other: &$T) -> $T {
  178. // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
  179. // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
  180. match *self % *other {
  181. r if (r > 0 && *other < 0)
  182. || (r < 0 && *other > 0) => r + *other,
  183. r => r,
  184. }
  185. }
  186. /// Calculates `div_floor` and `mod_floor` simultaneously
  187. #[inline]
  188. fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
  189. // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
  190. // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
  191. match self.div_rem(other) {
  192. (d, r) if (r > 0 && *other < 0)
  193. || (r < 0 && *other > 0) => (d - 1, r + *other),
  194. (d, r) => (d, r),
  195. }
  196. }
  197. /// Calculates the Greatest Common Divisor (GCD) of the number and
  198. /// `other`. The result is always positive.
  199. #[inline]
  200. fn gcd(&self, other: &$T) -> $T {
  201. // Use Euclid's algorithm
  202. let mut m = *self;
  203. let mut n = *other;
  204. while m != 0 {
  205. let temp = m;
  206. m = n % temp;
  207. n = temp;
  208. }
  209. n.abs()
  210. }
  211. /// Calculates the Lowest Common Multiple (LCM) of the number and
  212. /// `other`.
  213. #[inline]
  214. fn lcm(&self, other: &$T) -> $T {
  215. // should not have to recalculate abs
  216. ((*self * *other) / self.gcd(other)).abs()
  217. }
  218. /// Deprecated, use `is_multiple_of` instead.
  219. #[deprecated = "function renamed to `is_multiple_of`"]
  220. #[inline]
  221. fn divides(&self, other: &$T) -> bool { return self.is_multiple_of(other); }
  222. /// Returns `true` if the number is a multiple of `other`.
  223. #[inline]
  224. fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
  225. /// Returns `true` if the number is divisible by `2`
  226. #[inline]
  227. fn is_even(&self) -> bool { (*self) & 1 == 0 }
  228. /// Returns `true` if the number is not divisible by `2`
  229. #[inline]
  230. fn is_odd(&self) -> bool { !self.is_even() }
  231. /// Simultaneous truncated integer division and modulus.
  232. #[inline]
  233. fn div_rem(&self, other: &$T) -> ($T, $T) {
  234. (*self / *other, *self % *other)
  235. }
  236. }
  237. #[cfg(test)]
  238. mod $test_mod {
  239. use Integer;
  240. /// Checks that the division rule holds for:
  241. ///
  242. /// - `n`: numerator (dividend)
  243. /// - `d`: denominator (divisor)
  244. /// - `qr`: quotient and remainder
  245. #[cfg(test)]
  246. fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
  247. assert_eq!(d * q + r, n);
  248. }
  249. #[test]
  250. fn test_div_rem() {
  251. fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
  252. let (n,d) = nd;
  253. let separate_div_rem = (n / d, n % d);
  254. let combined_div_rem = n.div_rem(&d);
  255. assert_eq!(separate_div_rem, qr);
  256. assert_eq!(combined_div_rem, qr);
  257. test_division_rule(nd, separate_div_rem);
  258. test_division_rule(nd, combined_div_rem);
  259. }
  260. test_nd_dr(( 8, 3), ( 2, 2));
  261. test_nd_dr(( 8, -3), (-2, 2));
  262. test_nd_dr((-8, 3), (-2, -2));
  263. test_nd_dr((-8, -3), ( 2, -2));
  264. test_nd_dr(( 1, 2), ( 0, 1));
  265. test_nd_dr(( 1, -2), ( 0, 1));
  266. test_nd_dr((-1, 2), ( 0, -1));
  267. test_nd_dr((-1, -2), ( 0, -1));
  268. }
  269. #[test]
  270. fn test_div_mod_floor() {
  271. fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
  272. let (n,d) = nd;
  273. let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
  274. let combined_div_mod_floor = n.div_mod_floor(&d);
  275. assert_eq!(separate_div_mod_floor, dm);
  276. assert_eq!(combined_div_mod_floor, dm);
  277. test_division_rule(nd, separate_div_mod_floor);
  278. test_division_rule(nd, combined_div_mod_floor);
  279. }
  280. test_nd_dm(( 8, 3), ( 2, 2));
  281. test_nd_dm(( 8, -3), (-3, -1));
  282. test_nd_dm((-8, 3), (-3, 1));
  283. test_nd_dm((-8, -3), ( 2, -2));
  284. test_nd_dm(( 1, 2), ( 0, 1));
  285. test_nd_dm(( 1, -2), (-1, -1));
  286. test_nd_dm((-1, 2), (-1, 1));
  287. test_nd_dm((-1, -2), ( 0, -1));
  288. }
  289. #[test]
  290. fn test_gcd() {
  291. assert_eq!((10 as $T).gcd(&2), 2 as $T);
  292. assert_eq!((10 as $T).gcd(&3), 1 as $T);
  293. assert_eq!((0 as $T).gcd(&3), 3 as $T);
  294. assert_eq!((3 as $T).gcd(&3), 3 as $T);
  295. assert_eq!((56 as $T).gcd(&42), 14 as $T);
  296. assert_eq!((3 as $T).gcd(&-3), 3 as $T);
  297. assert_eq!((-6 as $T).gcd(&3), 3 as $T);
  298. assert_eq!((-4 as $T).gcd(&-2), 2 as $T);
  299. }
  300. #[test]
  301. fn test_lcm() {
  302. assert_eq!((1 as $T).lcm(&0), 0 as $T);
  303. assert_eq!((0 as $T).lcm(&1), 0 as $T);
  304. assert_eq!((1 as $T).lcm(&1), 1 as $T);
  305. assert_eq!((-1 as $T).lcm(&1), 1 as $T);
  306. assert_eq!((1 as $T).lcm(&-1), 1 as $T);
  307. assert_eq!((-1 as $T).lcm(&-1), 1 as $T);
  308. assert_eq!((8 as $T).lcm(&9), 72 as $T);
  309. assert_eq!((11 as $T).lcm(&5), 55 as $T);
  310. }
  311. #[test]
  312. fn test_even() {
  313. assert_eq!((-4 as $T).is_even(), true);
  314. assert_eq!((-3 as $T).is_even(), false);
  315. assert_eq!((-2 as $T).is_even(), true);
  316. assert_eq!((-1 as $T).is_even(), false);
  317. assert_eq!((0 as $T).is_even(), true);
  318. assert_eq!((1 as $T).is_even(), false);
  319. assert_eq!((2 as $T).is_even(), true);
  320. assert_eq!((3 as $T).is_even(), false);
  321. assert_eq!((4 as $T).is_even(), true);
  322. }
  323. #[test]
  324. fn test_odd() {
  325. assert_eq!((-4 as $T).is_odd(), false);
  326. assert_eq!((-3 as $T).is_odd(), true);
  327. assert_eq!((-2 as $T).is_odd(), false);
  328. assert_eq!((-1 as $T).is_odd(), true);
  329. assert_eq!((0 as $T).is_odd(), false);
  330. assert_eq!((1 as $T).is_odd(), true);
  331. assert_eq!((2 as $T).is_odd(), false);
  332. assert_eq!((3 as $T).is_odd(), true);
  333. assert_eq!((4 as $T).is_odd(), false);
  334. }
  335. }
  336. )
  337. }
  338. impl_integer_for_int!(i8, test_integer_i8)
  339. impl_integer_for_int!(i16, test_integer_i16)
  340. impl_integer_for_int!(i32, test_integer_i32)
  341. impl_integer_for_int!(i64, test_integer_i64)
  342. impl_integer_for_int!(int, test_integer_int)
  343. macro_rules! impl_integer_for_uint {
  344. ($T:ty, $test_mod:ident) => (
  345. impl Integer for $T {
  346. /// Unsigned integer division. Returns the same result as `div` (`/`).
  347. #[inline]
  348. fn div_floor(&self, other: &$T) -> $T { *self / *other }
  349. /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
  350. #[inline]
  351. fn mod_floor(&self, other: &$T) -> $T { *self % *other }
  352. /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
  353. #[inline]
  354. fn gcd(&self, other: &$T) -> $T {
  355. // Use Euclid's algorithm
  356. let mut m = *self;
  357. let mut n = *other;
  358. while m != 0 {
  359. let temp = m;
  360. m = n % temp;
  361. n = temp;
  362. }
  363. n
  364. }
  365. /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
  366. #[inline]
  367. fn lcm(&self, other: &$T) -> $T {
  368. (*self * *other) / self.gcd(other)
  369. }
  370. /// Deprecated, use `is_multiple_of` instead.
  371. #[deprecated = "function renamed to `is_multiple_of`"]
  372. #[inline]
  373. fn divides(&self, other: &$T) -> bool { return self.is_multiple_of(other); }
  374. /// Returns `true` if the number is a multiple of `other`.
  375. #[inline]
  376. fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
  377. /// Returns `true` if the number is divisible by `2`.
  378. #[inline]
  379. fn is_even(&self) -> bool { (*self) & 1 == 0 }
  380. /// Returns `true` if the number is not divisible by `2`.
  381. #[inline]
  382. fn is_odd(&self) -> bool { !(*self).is_even() }
  383. /// Simultaneous truncated integer division and modulus.
  384. #[inline]
  385. fn div_rem(&self, other: &$T) -> ($T, $T) {
  386. (*self / *other, *self % *other)
  387. }
  388. }
  389. #[cfg(test)]
  390. mod $test_mod {
  391. use Integer;
  392. #[test]
  393. fn test_div_mod_floor() {
  394. assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
  395. assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
  396. assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
  397. assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
  398. assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
  399. assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
  400. assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
  401. assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
  402. assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 as $T));
  403. }
  404. #[test]
  405. fn test_gcd() {
  406. assert_eq!((10 as $T).gcd(&2), 2 as $T);
  407. assert_eq!((10 as $T).gcd(&3), 1 as $T);
  408. assert_eq!((0 as $T).gcd(&3), 3 as $T);
  409. assert_eq!((3 as $T).gcd(&3), 3 as $T);
  410. assert_eq!((56 as $T).gcd(&42), 14 as $T);
  411. }
  412. #[test]
  413. fn test_lcm() {
  414. assert_eq!((1 as $T).lcm(&0), 0 as $T);
  415. assert_eq!((0 as $T).lcm(&1), 0 as $T);
  416. assert_eq!((1 as $T).lcm(&1), 1 as $T);
  417. assert_eq!((8 as $T).lcm(&9), 72 as $T);
  418. assert_eq!((11 as $T).lcm(&5), 55 as $T);
  419. assert_eq!((15 as $T).lcm(&17), 255 as $T);
  420. }
  421. #[test]
  422. fn test_is_multiple_of() {
  423. assert!((6 as $T).is_multiple_of(&(6 as $T)));
  424. assert!((6 as $T).is_multiple_of(&(3 as $T)));
  425. assert!((6 as $T).is_multiple_of(&(1 as $T)));
  426. }
  427. #[test]
  428. fn test_even() {
  429. assert_eq!((0 as $T).is_even(), true);
  430. assert_eq!((1 as $T).is_even(), false);
  431. assert_eq!((2 as $T).is_even(), true);
  432. assert_eq!((3 as $T).is_even(), false);
  433. assert_eq!((4 as $T).is_even(), true);
  434. }
  435. #[test]
  436. fn test_odd() {
  437. assert_eq!((0 as $T).is_odd(), false);
  438. assert_eq!((1 as $T).is_odd(), true);
  439. assert_eq!((2 as $T).is_odd(), false);
  440. assert_eq!((3 as $T).is_odd(), true);
  441. assert_eq!((4 as $T).is_odd(), false);
  442. }
  443. }
  444. )
  445. }
  446. impl_integer_for_uint!(u8, test_integer_u8)
  447. impl_integer_for_uint!(u16, test_integer_u16)
  448. impl_integer_for_uint!(u32, test_integer_u32)
  449. impl_integer_for_uint!(u64, test_integer_u64)
  450. impl_integer_for_uint!(uint, test_integer_uint)