random.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. use ibig::{ibig, ops::DivRem, ubig, UBig};
  2. use rand::{distributions::uniform::Uniform, prelude::*};
  3. #[test]
  4. fn test_uniform_ubig() {
  5. let mut rng = StdRng::seed_from_u64(1);
  6. let distr = Uniform::from(ubig!(3)..ubig!(7));
  7. let x = (&mut rng).sample_iter(&distr).take(1000).min().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  8. assert_eq!(x, ubig!(3));
  9. let x = (&mut rng).sample_iter(&distr).take(1000).max().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  10. assert_eq!(x, ubig!(6));
  11. let distr = Uniform::from(ubig!(3)..=ubig!(7));
  12. let x = (&mut rng).sample_iter(&distr).take(1000).min().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  13. assert_eq!(x, ubig!(3));
  14. let x = (&mut rng).sample_iter(&distr).take(1000).max().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  15. assert_eq!(x, ubig!(7));
  16. let distr = Uniform::from(ubig!(0b100) << 128..ubig!(0b1000) << 128);
  17. let x = (&mut rng).sample_iter(&distr).take(1000).min().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  18. assert!(x >= ubig!(0b100) << 128 && x < ubig!(0b101) << 128);
  19. let x = (&mut rng).sample_iter(&distr).take(1000).max().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  20. assert!(x >= ubig!(0b111) << 128 && x < ubig!(0b1000) << 128);
  21. }
  22. #[test]
  23. fn test_uniform_ibig() {
  24. let mut rng = StdRng::seed_from_u64(1);
  25. let distr = Uniform::from(ibig!(-7)..ibig!(3));
  26. let x = (&mut rng).sample_iter(&distr).take(1000).min().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  27. assert_eq!(x, ibig!(-7));
  28. let x = (&mut rng).sample_iter(&distr).take(1000).max().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  29. assert_eq!(x, ibig!(2));
  30. let distr = Uniform::from(ibig!(-7)..=ibig!(3));
  31. let x = (&mut rng).sample_iter(&distr).take(1000).min().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  32. assert_eq!(x, ibig!(-7));
  33. let x = (&mut rng).sample_iter(&distr).take(1000).max().unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA")));
  34. assert_eq!(x, ibig!(3));
  35. }
  36. #[test]
  37. fn test_random_arithmetic() {
  38. let mut rng = StdRng::seed_from_u64(3);
  39. let p = ubig!(1000000007);
  40. // 10^2 bits: 10^5 cases
  41. // 10^6 bits: 10 cases
  42. for log_num_bits in 2..=6 {
  43. let num_bits = match 10usize.checked_pow(log_num_bits) {
  44. None => continue,
  45. Some(x) if x > UBig::MAX_BIT_LEN / 2 - 10 => continue,
  46. Some(x) => x,
  47. };
  48. let num_cases = 10u32.pow(7 - log_num_bits);
  49. for _ in 0..num_cases {
  50. let len_a = (&mut rng).gen_range(10..num_bits);
  51. let len_b = (&mut rng).gen_range(10..num_bits);
  52. let a = (&mut rng).gen_range(ubig!(100)..ubig!(1) << len_a);
  53. let b = (&mut rng).gen_range(ubig!(100)..ubig!(1) << len_b);
  54. let c = (&mut rng).sample(Uniform::new(ubig!(0), &a));
  55. let radix = (&mut rng).gen_range(2..=36);
  56. assert_eq!((&a + &b) % &p, ((&a % &p) + (&b % &p)) % &p);
  57. assert_eq!(&a + &b - &a, b);
  58. assert_eq!((&a * &b) % &p, ((&a % &p) * (&b % &p)) % &p);
  59. let (quot, rem) = (&a * &b + &c).div_rem(&a);
  60. assert_eq!(quot, b);
  61. assert_eq!(rem, c);
  62. assert_eq!(
  63. UBig::from_str_radix(&a.in_radix(radix).to_string(), radix).unwrap_or_else(|| panic!("Panicked at {}:{} (git sha: {:?})", file!(), line!(), option_env!("GIT_SHA"))),
  64. a
  65. )
  66. }
  67. }
  68. }