use crate::int::types::Int;
#[allow(dead_code)]
#[inline]
pub(crate) const fn eq_xor_fold<const N: usize>(a: Int<N>, b: Int<N>) -> bool {
let al = a.as_limbs();
let bl = b.as_limbs();
let mut diff: u64 = 0;
let mut i = 0;
while i < N {
diff |= al[i] ^ bl[i];
i += 1;
}
diff == 0
}
#[cfg(test)]
mod tests {
use super::eq_xor_fold;
use crate::int::algos::eq::eq_limbwise::eq_limbwise;
use crate::int::types::Int;
fn diff_at<const N: usize>(seeds: &[u64]) {
for &seed in seeds {
let mut la = [0u64; N];
let mut s = seed;
for limb in la.iter_mut() {
s = s.wrapping_add(0x9E37_79B9_7F4A_7C15);
let mut z = s;
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
*limb = z ^ (z >> 31);
}
let a = Int::<N>::from_limbs(la);
assert_eq!(eq_xor_fold::<N>(a, a), eq_limbwise::<N>(a, a));
assert!(eq_xor_fold::<N>(a, a));
let mut lb = la;
lb[0] ^= 1;
let b = Int::<N>::from_limbs(lb);
assert_eq!(eq_xor_fold::<N>(a, b), eq_limbwise::<N>(a, b));
assert!(!eq_xor_fold::<N>(a, b));
let mut lc = la;
lc[N - 1] ^= 1 << 63;
let c = Int::<N>::from_limbs(lc);
assert_eq!(eq_xor_fold::<N>(a, c), eq_limbwise::<N>(a, c));
assert!(!eq_xor_fold::<N>(a, c));
}
}
#[test]
fn eq_xor_fold_matches_limbwise_all_widths() {
let seeds: [u64; 6] = [1, 2, 3, 0xDEAD_BEEF, 0xFFFF_FFFF_FFFF_FFFF, 0x1357_9BDF];
diff_at::<1>(&seeds);
diff_at::<2>(&seeds);
diff_at::<3>(&seeds);
diff_at::<4>(&seeds);
diff_at::<8>(&seeds);
diff_at::<16>(&seeds);
}
#[test]
fn eq_xor_fold_sign_boundaries() {
let min = Int::<2>::from_i128(i128::MIN);
let max = Int::<2>::from_i128(i128::MAX);
let zero = Int::<2>::from_i64(0);
let neg1 = Int::<2>::from_i64(-1);
assert!(eq_xor_fold::<2>(min, min));
assert!(eq_xor_fold::<2>(max, max));
assert!(!eq_xor_fold::<2>(min, max));
assert!(eq_xor_fold::<2>(zero, zero));
assert!(!eq_xor_fold::<2>(zero, neg1));
}
}