use geoit::scalar::*;
#[test]
fn rat_add_large_denominators() {
let a = Rat::new(1, i64::MAX as i128);
let b = Rat::new(1, i64::MAX as i128);
let c = a + b;
assert_eq!(c, Rat::new(2, i64::MAX as i128));
}
#[test]
fn rat_mul_near_boundary() {
let a = Rat::new(i64::MAX as i128, 7);
let b = Rat::new(7, i64::MAX as i128);
let c = a * b;
assert_eq!(c, Rat::ONE);
}
#[test]
fn rat_ordering_comprehensive() {
let values = vec![
Rat::new(-100, 1),
Rat::new(-1, 2),
Rat::ZERO,
Rat::new(1, 1000),
Rat::new(1, 2),
Rat::ONE,
Rat::new(100, 1),
];
for i in 0..values.len() {
for j in (i + 1)..values.len() {
assert!(
values[i] < values[j],
"{} should be < {}",
values[i],
values[j]
);
}
}
}
#[test]
fn rat_arithmetic_identities() {
let half = Rat::new(1, 2);
let third = Rat::new(1, 3);
assert_eq!(half + third, Rat::new(5, 6));
assert_eq!(half * third, Rat::new(1, 6));
assert_eq!(half / third, Rat::new(3, 2));
assert_eq!(-half + half, Rat::ZERO);
}
#[test]
fn bigint_from_i128_extremes() {
let max = BigInt::from(i128::MAX);
let min = BigInt::from(i128::MIN);
assert_eq!(max.to_i128(), Some(i128::MAX));
assert_eq!(min.to_i128(), Some(i128::MIN));
}
#[test]
fn bigint_arithmetic_beyond_i128() {
let max = BigInt::from(i128::MAX);
let one = BigInt::from(1i128);
let beyond = max.add(&one);
assert!(beyond.to_i128().is_none());
assert_eq!(beyond.sub(&one).to_i128(), Some(i128::MAX));
}
#[test]
fn bigint_mul_large() {
let a = BigInt::from(1u128 << 64);
let b = BigInt::from(1u128 << 64);
let c = a.mul(&b);
assert!(c.to_i128().is_none()); assert!(c.is_positive());
}
#[test]
fn bigint_gcd_large() {
let a = BigInt::from(i128::MAX);
let b = BigInt::from(i128::MAX - 1);
let g = a.gcd(&b);
assert_eq!(g.to_i128(), Some(1)); }
#[test]
fn biguint_div_roundtrip_large() {
let a = BigUint::from_u128(u128::MAX);
let b = BigUint::from_u128(12345678901234567890u128);
let (q, r) = a.div_rem(&b);
let reconstructed = q.mul(&b).add(&r);
assert_eq!(reconstructed, a);
}
#[test]
fn bigrat_promotion_demotion_cycle() {
let r = Rat::new(355, 113);
let b = BigRat::from_rat(r);
let b2 = b.mul(&b);
let b2_back = b2.to_rat();
assert!(b2_back.is_some());
let r2 = b2_back.unwrap();
assert_eq!(r2, r * r);
}
#[test]
fn bigrat_stays_canonical() {
let a = BigRat::from_i128_pair(6, 4);
let b = BigRat::from_i128_pair(3, 2);
assert_eq!(a, b);
}
#[test]
fn scalar_rat_plus_rat() {
let a = Scalar::from(3i64);
let b = Scalar::from(4i64);
let c = a + b;
assert!(matches!(c, Scalar::Rat(_)));
assert_eq!(c.try_as_rat(), Some(Rat::from(7)));
}
#[test]
fn scalar_rat_plus_radical() {
let a = Scalar::from(1i64);
let b = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let c = a + b;
assert!(matches!(c, Scalar::Radical(_)));
assert!(!c.is_zero());
}
#[test]
fn scalar_overflow_promotes_to_big() {
let big = Scalar::Rat(Rat::new(i128::MAX / 2 + 1, 1));
let result = big.clone() + big;
assert!(result.is_big());
}
#[test]
fn scalar_big_demotes_on_cancellation() {
let a = Scalar::Big(BigRat::from_i128(42));
let b = Scalar::Big(BigRat::from_i128(42));
let c = a - b;
assert!(c.is_zero());
assert!(matches!(c, Scalar::Rat(_)));
}
#[test]
fn scalar_big_times_zero_is_zero() {
let big = Scalar::Big(BigRat::from_i128(999));
let zero = Scalar::from(0i64);
let result = big * zero;
assert!(result.is_zero());
}
#[test]
fn scalar_ord_rat_comprehensive() {
let vals: Vec<Scalar> = vec![
Scalar::from(-10i64),
Scalar::from(-1i64),
Scalar::from(0i64),
Scalar::from(1i64),
Scalar::from(10i64),
];
for i in 0..vals.len() {
for j in (i + 1)..vals.len() {
assert!(vals[i] < vals[j], "{} should be < {}", vals[i], vals[j]);
}
}
}
#[test]
fn scalar_ord_transitivity() {
let a = Scalar::from(-5i64);
let b = Scalar::from(0i64);
let c = Scalar::from(5i64);
assert!(a < b && b < c && a < c);
}
#[test]
fn scalar_ord_antisymmetry() {
let a = Scalar::from(3i64);
let b = Scalar::from(7i64);
assert!(a < b);
assert!(b > a);
assert!(!(a > b));
assert!(!(b < a));
}
#[test]
fn scalar_ord_big_vs_rat_equal() {
let big = Scalar::Big(BigRat::from_i128(42));
let rat = Scalar::from(42i64);
assert_eq!(big, rat);
assert!(!(big < rat));
assert!(!(big > rat));
}
#[test]
fn scalar_ord_radical_vs_rat() {
let sqrt2 = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
assert!(Scalar::from(1i64) < sqrt2);
assert!(sqrt2 < Scalar::from(2i64));
}
#[test]
fn scalar_radical_cross_tower_add() {
let a = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let b = Scalar::Radical(RadicalElement::sqrt(Rat::from(3)));
let sum = a + b;
assert!(!sum.is_zero());
assert!(matches!(sum, Scalar::Radical(_)));
}
#[test]
fn scalar_radical_same_tower_cancels() {
use std::sync::Arc;
let tower = Arc::new(RadicalTower::single(RadicalLayer::sqrt(Rat::from(2))));
let a = Scalar::Radical(RadicalElement::new(
vec![Coeff::ONE, Coeff::ONE],
Arc::clone(&tower),
));
let b = Scalar::Radical(RadicalElement::new(
vec![Coeff::Rat(Rat::from(2)), Coeff::Rat(-Rat::ONE)],
tower,
));
let sum = a + b;
assert_eq!(sum, Scalar::from(3i64));
}
#[test]
fn scalar_radical_cross_tower_mul() {
let a = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let b = Scalar::Radical(RadicalElement::sqrt(Rat::from(3)));
let product = a * b;
assert!(!product.is_zero());
assert!(matches!(product, Scalar::Radical(_)));
}
#[test]
fn scalar_radical_from_trait() {
let r = RadicalElement::sqrt(Rat::from(5));
let s = Scalar::from(r);
assert!(matches!(s, Scalar::Radical(_)));
assert!(!s.is_zero());
}
#[test]
fn scalar_radical_rat_demotion() {
let r = RadicalElement::from_rat(Rat::from(42));
let s = Scalar::from(r);
assert_eq!(s, Scalar::from(42i64));
assert!(matches!(s, Scalar::Rat(_)));
}
#[test]
fn scalar_radical_add_rat() {
let three = Scalar::from(3i64);
let sqrt2 = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let sum = three + sqrt2;
assert!(!sum.is_zero());
assert!(matches!(sum, Scalar::Radical(_)));
}
#[test]
fn scalar_radical_mul_produces_rat() {
let a = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let b = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let product = a * b;
assert_eq!(product, Scalar::from(2i64));
}
#[test]
fn scalar_radical_equality_cross_type() {
let a = Scalar::from(3i64);
let b = Scalar::Radical(RadicalElement::from_rat(Rat::from(3)));
assert_eq!(a, b);
}
#[test]
fn scalar_radical_ordering() {
let one = Scalar::from(1i64);
let sqrt2 = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let two = Scalar::from(2i64);
assert!(one < sqrt2);
assert!(sqrt2 < two);
}
#[test]
fn scalar_radical_cross_tower_div() {
let a = Scalar::Radical(RadicalElement::sqrt(Rat::from(2)));
let b = Scalar::Radical(RadicalElement::sqrt(Rat::from(3)));
let quotient = a / b;
assert!(!quotient.is_zero());
assert!(matches!(quotient, Scalar::Radical(_)));
}