add.rs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. use core::fmt::Debug;
  2. use core::ops::{Add, AddAssign, Sub, SubAssign};
  3. use ibig::{ibig, ubig};
  4. /// Test a + b = c in various ways.
  5. fn test_add_sub<'a, T>(a: &'a T, b: &'a T, c: &'a T)
  6. where
  7. T: Add<T, Output = T>,
  8. T: Add<&'a T, Output = T>,
  9. &'a T: Add<T, Output = T>,
  10. &'a T: Add<&'a T, Output = T>,
  11. T: AddAssign<T>,
  12. T: AddAssign<&'a T>,
  13. T: Sub<T, Output = T>,
  14. T: Sub<&'a T, Output = T>,
  15. &'a T: Sub<T, Output = T>,
  16. &'a T: Sub<&'a T, Output = T>,
  17. T: SubAssign<T>,
  18. T: SubAssign<&'a T>,
  19. T: Clone,
  20. T: Debug,
  21. T: Eq,
  22. {
  23. assert_eq!(a + b, *c);
  24. assert_eq!(a.clone() + b, *c);
  25. assert_eq!(a + b.clone(), *c);
  26. assert_eq!(a.clone() + b.clone(), *c);
  27. let mut x = a.clone();
  28. x += b;
  29. assert_eq!(x, *c);
  30. let mut x = a.clone();
  31. x += b.clone();
  32. assert_eq!(x, *c);
  33. assert_eq!(c - a, *b);
  34. assert_eq!(c.clone() - a, *b);
  35. assert_eq!(c - a.clone(), *b);
  36. assert_eq!(c.clone() - a.clone(), *b);
  37. let mut x = c.clone();
  38. x -= a;
  39. assert_eq!(x, *b);
  40. let mut x = c.clone();
  41. x -= a.clone();
  42. assert_eq!(x, *b);
  43. }
  44. // FIXME: ibig makes invalid assumptions about how Vec works, we need to audit this.
  45. #[test]
  46. #[ignore]
  47. fn test_add_sub_ubig() {
  48. let test_cases = [
  49. (ubig!(3), ubig!(4), ubig!(7)),
  50. (
  51. ubig!(0xffffffffffffffff),
  52. ubig!(1),
  53. ubig!(0x10000000000000000),
  54. ),
  55. (
  56. ubig!(0x10000000000000003),
  57. ubig!(4),
  58. ubig!(0x10000000000000007),
  59. ),
  60. (
  61. ubig!(0xeeeeeeeeeeeeeeeeffffffffffffffff),
  62. ubig!(1),
  63. ubig!(0xeeeeeeeeeeeeeeef0000000000000000),
  64. ),
  65. (
  66. ubig!(0xeeeeeeeeeeeeeeeeffffffffffffffff),
  67. ubig!(1),
  68. ubig!(0xeeeeeeeeeeeeeeef0000000000000000),
  69. ),
  70. (
  71. ubig!(0xffffffffffffffffffffffffffffffff),
  72. ubig!(2),
  73. ubig!(_0x100000000000000000000000000000001),
  74. ),
  75. (
  76. ubig!(0x88888888888888888888888888888888),
  77. ubig!(0x88888888888888888888888888888888),
  78. ubig!(_0x111111111111111111111111111111110),
  79. ),
  80. (
  81. ubig!(_0x888888888888888888888888888888888888888888888888),
  82. ubig!(0x88888888888888888888888888888888),
  83. ubig!(_0x888888888888888911111111111111111111111111111110),
  84. ),
  85. (
  86. ubig!(_0x888888888888888888888888888888888888888888888888),
  87. ubig!(0),
  88. ubig!(_0x888888888888888888888888888888888888888888888888),
  89. ),
  90. ];
  91. for (a, b, c) in &test_cases {
  92. test_add_sub(a, b, c);
  93. test_add_sub(b, a, c);
  94. }
  95. }
  96. #[test]
  97. #[should_panic]
  98. fn test_sub_ubig_overflow() {
  99. let _ = ubig!(3) - ubig!(4);
  100. }
  101. // FIXME: ibig makes invalid assumptions about how Vec works, we need to audit this.
  102. #[test]
  103. #[ignore]
  104. fn test_add_sub_ibig() {
  105. let test_cases = [
  106. (ibig!(3), ibig!(4), ibig!(7)),
  107. (ibig!(3), ibig!(-4), ibig!(-1)),
  108. (ibig!(-3), ibig!(4), ibig!(1)),
  109. (ibig!(-3), ibig!(-4), ibig!(-7)),
  110. (
  111. ibig!(0x10000000000000000),
  112. ibig!(-4),
  113. ibig!(0xfffffffffffffffc),
  114. ),
  115. (
  116. ibig!(0x10000000000000000),
  117. ibig!(_0x200000000000000000000000000000000),
  118. ibig!(_0x200000000000000010000000000000000),
  119. ),
  120. (
  121. ibig!(-_0x200000000000000010000000000000000),
  122. ibig!(_0x200000000000000000000000000000000),
  123. ibig!(-0x10000000000000000),
  124. ),
  125. (
  126. ibig!(_0x200000000000000010000000000000000),
  127. ibig!(-_0x200000000000000000000000000000000),
  128. ibig!(0x10000000000000000),
  129. ),
  130. ];
  131. for (a, b, c) in &test_cases {
  132. test_add_sub(a, b, c);
  133. test_add_sub(b, a, c);
  134. }
  135. }
  136. #[test]
  137. #[allow(clippy::op_ref)]
  138. fn test_add_sub_ubig_primitive() {
  139. assert_eq!(ubig!(3) + 7u16, ubig!(10));
  140. assert_eq!(ubig!(3) + &7u16, ubig!(10));
  141. assert_eq!(&ubig!(3) + 7u16, ubig!(10));
  142. assert_eq!(&ubig!(3) + &7u16, ubig!(10));
  143. assert_eq!(7u16 + ubig!(3), ubig!(10));
  144. assert_eq!(7u16 + &ubig!(3), ubig!(10));
  145. assert_eq!(&7u16 + ubig!(3), ubig!(10));
  146. assert_eq!(&7u16 + &ubig!(3), ubig!(10));
  147. let mut x = ubig!(3);
  148. x += 3u8;
  149. x += &3u8;
  150. assert_eq!(x, ubig!(9));
  151. assert_eq!(ubig!(7) - 5u16, ubig!(2));
  152. assert_eq!(ubig!(7) - &5u16, ubig!(2));
  153. assert_eq!(&ubig!(7) - 5u16, ubig!(2));
  154. assert_eq!(&ubig!(7) - &5u16, ubig!(2));
  155. let mut x = ubig!(10);
  156. x -= 1u8;
  157. x -= &2u8;
  158. assert_eq!(x, ubig!(7));
  159. assert_eq!(ubig!(3) + (-1), ubig!(2));
  160. assert_eq!(ubig!(3) + &(-1), ubig!(2));
  161. assert_eq!(&ubig!(3) + (-1), ubig!(2));
  162. assert_eq!(&ubig!(3) + &(-1), ubig!(2));
  163. assert_eq!((-1) + ubig!(3), ubig!(2));
  164. assert_eq!((-1) + &ubig!(3), ubig!(2));
  165. assert_eq!(&(-1) + ubig!(3), ubig!(2));
  166. assert_eq!(&(-1) + &ubig!(3), ubig!(2));
  167. let mut x = ubig!(3);
  168. x += -1;
  169. x += &2;
  170. assert_eq!(x, ubig!(4));
  171. assert_eq!(ubig!(3) - (-1), ubig!(4));
  172. assert_eq!(ubig!(3) - &(-1), ubig!(4));
  173. assert_eq!(&ubig!(3) - (-1), ubig!(4));
  174. assert_eq!(&ubig!(3) - &(-1), ubig!(4));
  175. let mut x = ubig!(3);
  176. x -= -1;
  177. x -= &2;
  178. assert_eq!(x, ubig!(2));
  179. }
  180. #[test]
  181. #[should_panic]
  182. fn test_add_ubig_primitive_overflow() {
  183. let _ = ubig!(3) + (-5i16);
  184. }
  185. #[test]
  186. #[should_panic]
  187. fn test_sub_ubig_primitive_overflow() {
  188. let _ = ubig!(3) - 5u16;
  189. }
  190. #[test]
  191. #[allow(clippy::op_ref)]
  192. fn test_add_sub_ibig_primitive() {
  193. assert_eq!(ibig!(-3) + 7u16, ibig!(4));
  194. assert_eq!(ibig!(-3) + &7u16, ibig!(4));
  195. assert_eq!(&ibig!(-3) + 7u16, ibig!(4));
  196. assert_eq!(&ibig!(-3) + &7u16, ibig!(4));
  197. assert_eq!(7u16 + ibig!(-3), ibig!(4));
  198. assert_eq!(7u16 + &ibig!(-3), ibig!(4));
  199. assert_eq!(&7u16 + ibig!(-3), ibig!(4));
  200. assert_eq!(&7u16 + &ibig!(-3), ibig!(4));
  201. let mut x = ibig!(-3);
  202. x += 3u8;
  203. x += &3u8;
  204. assert_eq!(x, ibig!(3));
  205. assert_eq!(ibig!(7) - 5u16, ibig!(2));
  206. assert_eq!(ibig!(7) - &5u16, ibig!(2));
  207. assert_eq!(&ibig!(7) - 5u16, ibig!(2));
  208. assert_eq!(&ibig!(7) - &5u16, ibig!(2));
  209. assert_eq!(5u16 - ibig!(7), ibig!(-2));
  210. assert_eq!(5u16 - &ibig!(7), ibig!(-2));
  211. assert_eq!(&5u16 - ibig!(7), ibig!(-2));
  212. assert_eq!(&5u16 - &ibig!(7), ibig!(-2));
  213. let mut x = ibig!(10);
  214. x -= 7u8;
  215. x -= &7u8;
  216. assert_eq!(x, ibig!(-4));
  217. assert_eq!(ibig!(3) + (-1), ibig!(2));
  218. assert_eq!(ibig!(3) + &(-1), ibig!(2));
  219. assert_eq!(&ibig!(3) + (-1), ibig!(2));
  220. assert_eq!(&ibig!(3) + &(-1), ibig!(2));
  221. assert_eq!(-1 + ibig!(3), ibig!(2));
  222. assert_eq!(-1 + &ibig!(3), ibig!(2));
  223. assert_eq!(&-1 + ibig!(3), ibig!(2));
  224. assert_eq!(&-1 + &ibig!(3), ibig!(2));
  225. let mut x = ibig!(3);
  226. x += -10;
  227. x += &20;
  228. assert_eq!(x, ibig!(13));
  229. assert_eq!(ibig!(3) - -1, ibig!(4));
  230. assert_eq!(ibig!(3) - &-1, ibig!(4));
  231. assert_eq!(&ibig!(3) - -1, ibig!(4));
  232. assert_eq!(&ibig!(3) - &-1, ibig!(4));
  233. assert_eq!(3 - ibig!(4), ibig!(-1));
  234. assert_eq!(3 - &ibig!(4), ibig!(-1));
  235. assert_eq!(&3 - ibig!(4), ibig!(-1));
  236. assert_eq!(&3 - &ibig!(4), ibig!(-1));
  237. let mut x = ibig!(3);
  238. x -= -1;
  239. x -= &10;
  240. assert_eq!(x, ibig!(-6));
  241. }