bigint_scalar.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. use num_bigint::BigInt;
  2. use num_bigint::Sign::Plus;
  3. use num_traits::{One, Signed, ToPrimitive, Zero};
  4. use std::ops::Neg;
  5. use std::panic::catch_unwind;
  6. mod consts;
  7. use crate::consts::*;
  8. #[macro_use]
  9. mod macros;
  10. #[test]
  11. fn test_scalar_add() {
  12. fn check(x: &BigInt, y: &BigInt, z: &BigInt) {
  13. let (x, y, z) = (x.clone(), y.clone(), z.clone());
  14. assert_signed_scalar_op!(x + y == z);
  15. assert_signed_scalar_assign_op!(x += y == z);
  16. }
  17. for elm in SUM_TRIPLES.iter() {
  18. let (a_vec, b_vec, c_vec) = *elm;
  19. let a = BigInt::from_slice(Plus, a_vec);
  20. let b = BigInt::from_slice(Plus, b_vec);
  21. let c = BigInt::from_slice(Plus, c_vec);
  22. let (na, nb, nc) = (-&a, -&b, -&c);
  23. check(&a, &b, &c);
  24. check(&b, &a, &c);
  25. check(&c, &na, &b);
  26. check(&c, &nb, &a);
  27. check(&a, &nc, &nb);
  28. check(&b, &nc, &na);
  29. check(&na, &nb, &nc);
  30. check(&a, &na, &Zero::zero());
  31. }
  32. }
  33. #[test]
  34. fn test_scalar_sub() {
  35. fn check(x: &BigInt, y: &BigInt, z: &BigInt) {
  36. let (x, y, z) = (x.clone(), y.clone(), z.clone());
  37. assert_signed_scalar_op!(x - y == z);
  38. assert_signed_scalar_assign_op!(x -= y == z);
  39. }
  40. for elm in SUM_TRIPLES.iter() {
  41. let (a_vec, b_vec, c_vec) = *elm;
  42. let a = BigInt::from_slice(Plus, a_vec);
  43. let b = BigInt::from_slice(Plus, b_vec);
  44. let c = BigInt::from_slice(Plus, c_vec);
  45. let (na, nb, nc) = (-&a, -&b, -&c);
  46. check(&c, &a, &b);
  47. check(&c, &b, &a);
  48. check(&nb, &a, &nc);
  49. check(&na, &b, &nc);
  50. check(&b, &na, &c);
  51. check(&a, &nb, &c);
  52. check(&nc, &na, &nb);
  53. check(&a, &a, &Zero::zero());
  54. }
  55. }
  56. #[test]
  57. fn test_scalar_mul() {
  58. fn check(x: &BigInt, y: &BigInt, z: &BigInt) {
  59. let (x, y, z) = (x.clone(), y.clone(), z.clone());
  60. assert_signed_scalar_op!(x * y == z);
  61. assert_signed_scalar_assign_op!(x *= y == z);
  62. }
  63. for elm in MUL_TRIPLES.iter() {
  64. let (a_vec, b_vec, c_vec) = *elm;
  65. let a = BigInt::from_slice(Plus, a_vec);
  66. let b = BigInt::from_slice(Plus, b_vec);
  67. let c = BigInt::from_slice(Plus, c_vec);
  68. let (na, nb, nc) = (-&a, -&b, -&c);
  69. check(&a, &b, &c);
  70. check(&b, &a, &c);
  71. check(&na, &nb, &c);
  72. check(&na, &b, &nc);
  73. check(&nb, &a, &nc);
  74. }
  75. }
  76. #[test]
  77. fn test_scalar_div_rem() {
  78. fn check_sub(a: &BigInt, b: u32, ans_q: &BigInt, ans_r: &BigInt) {
  79. let (q, r) = (a / b, a % b);
  80. if !r.is_zero() {
  81. assert_eq!(r.sign(), a.sign());
  82. }
  83. assert!(r.abs() <= BigInt::from(b));
  84. assert!(*a == b * &q + &r);
  85. assert!(q == *ans_q);
  86. assert!(r == *ans_r);
  87. let b = BigInt::from(b);
  88. let (a, ans_q, ans_r) = (a.clone(), ans_q.clone(), ans_r.clone());
  89. assert_signed_scalar_op!(a / b == ans_q);
  90. assert_signed_scalar_op!(a % b == ans_r);
  91. assert_signed_scalar_assign_op!(a /= b == ans_q);
  92. assert_signed_scalar_assign_op!(a %= b == ans_r);
  93. let nb = -b;
  94. assert_signed_scalar_op!(a / nb == -ans_q.clone());
  95. assert_signed_scalar_op!(a % nb == ans_r);
  96. assert_signed_scalar_assign_op!(a /= nb == -ans_q.clone());
  97. assert_signed_scalar_assign_op!(a %= nb == ans_r);
  98. }
  99. fn check(a: &BigInt, b: u32, q: &BigInt, r: &BigInt) {
  100. check_sub(a, b, q, r);
  101. check_sub(&a.neg(), b, &q.neg(), &r.neg());
  102. }
  103. for elm in MUL_TRIPLES.iter() {
  104. let (a_vec, b_vec, c_vec) = *elm;
  105. let a = BigInt::from_slice(Plus, a_vec);
  106. let b = BigInt::from_slice(Plus, b_vec);
  107. let c = BigInt::from_slice(Plus, c_vec);
  108. if a_vec.len() == 1 && a_vec[0] != 0 {
  109. let a = a_vec[0];
  110. check(&c, a, &b, &Zero::zero());
  111. }
  112. if b_vec.len() == 1 && b_vec[0] != 0 {
  113. let b = b_vec[0];
  114. check(&c, b, &a, &Zero::zero());
  115. }
  116. }
  117. for elm in DIV_REM_QUADRUPLES.iter() {
  118. let (a_vec, b_vec, c_vec, d_vec) = *elm;
  119. let a = BigInt::from_slice(Plus, a_vec);
  120. let c = BigInt::from_slice(Plus, c_vec);
  121. let d = BigInt::from_slice(Plus, d_vec);
  122. if b_vec.len() == 1 && b_vec[0] != 0 {
  123. let b = b_vec[0];
  124. check(&a, b, &c, &d);
  125. }
  126. }
  127. }
  128. #[test]
  129. fn test_scalar_div_rem_zero() {
  130. catch_unwind(|| BigInt::zero() / 0u32).unwrap_err();
  131. catch_unwind(|| BigInt::zero() % 0u32).unwrap_err();
  132. catch_unwind(|| BigInt::one() / 0u32).unwrap_err();
  133. catch_unwind(|| BigInt::one() % 0u32).unwrap_err();
  134. }