mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 04:27:45 +00:00
factor::numeric: Add more property-based tests (#1577)
* factor::numeric::gcd: Rename test against the Euclidean algorithm * factor::numeric::gcd: Add various property-based tests * factor::numeric::modular_inverse: Rename test * factor::numeric::modular_inverse: Add test on random values
This commit is contained in:
parent
70828329ba
commit
34a5941ee9
2 changed files with 48 additions and 4 deletions
|
@ -51,7 +51,7 @@ mod tests {
|
||||||
use quickcheck::quickcheck;
|
use quickcheck::quickcheck;
|
||||||
|
|
||||||
quickcheck! {
|
quickcheck! {
|
||||||
fn gcd(a: u64, b: u64) -> bool {
|
fn euclidean(a: u64, b: u64) -> bool {
|
||||||
// Test against the Euclidean algorithm
|
// Test against the Euclidean algorithm
|
||||||
let g = {
|
let g = {
|
||||||
let (mut a, mut b) = (a, b);
|
let (mut a, mut b) = (a, b);
|
||||||
|
@ -61,7 +61,38 @@ mod tests {
|
||||||
}
|
}
|
||||||
a
|
a
|
||||||
};
|
};
|
||||||
super::gcd(a, b) == g
|
gcd(a, b) == g
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one(a: u64) -> bool {
|
||||||
|
gcd(1, a) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn divisor(a: u64, b: u64) -> bool {
|
||||||
|
// Test that gcd(a, b) divides a and b
|
||||||
|
let g = gcd(a, b);
|
||||||
|
a % g == 0 && b % g == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn commutative(a: u64, b: u64) -> bool {
|
||||||
|
gcd(a, b) == gcd(b, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn associative(a: u64, b: u64, c: u64) -> bool {
|
||||||
|
gcd(a, gcd(b, c)) == gcd(gcd(a, b), c)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn scalar_mult(a: u64, b: u64, k: u64) -> bool {
|
||||||
|
gcd(k * a, k * b) == k * gcd(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn multiplicative(a: u64, b: u64, c: u64) -> bool {
|
||||||
|
// gcd(ab, c) = gcd(a, c) gcd(b, c) when a and b coprime
|
||||||
|
gcd(a, b) != 1 || gcd(a * b, c) == gcd(a, c) * gcd(b, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn linearity(a: u64, b: u64, k: u64) -> bool {
|
||||||
|
gcd(a + k * b, b) == gcd(a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ pub(crate) fn modular_inverse<T: Int>(a: T) -> T {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{super::traits::Int, *};
|
use super::{super::traits::Int, *};
|
||||||
use crate::parametrized_check;
|
use crate::parametrized_check;
|
||||||
|
use quickcheck::quickcheck;
|
||||||
|
|
||||||
fn test_inverter<T: Int>() {
|
fn small_values<T: Int>() {
|
||||||
// All odd integers from 1 to 20 000
|
// All odd integers from 1 to 20 000
|
||||||
let one = T::from(1).unwrap();
|
let one = T::from(1).unwrap();
|
||||||
let two = T::from(2).unwrap();
|
let two = T::from(2).unwrap();
|
||||||
|
@ -58,5 +59,17 @@ mod tests {
|
||||||
|
|
||||||
assert!(test_values.all(|x| x.wrapping_mul(&modular_inverse(x)) == one));
|
assert!(test_values.all(|x| x.wrapping_mul(&modular_inverse(x)) == one));
|
||||||
}
|
}
|
||||||
parametrized_check!(test_inverter);
|
parametrized_check!(small_values);
|
||||||
|
|
||||||
|
quickcheck! {
|
||||||
|
fn random_values_u32(n: u32) -> bool {
|
||||||
|
let n = 2 * n + 1;
|
||||||
|
modular_inverse(n).wrapping_mul(n) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_values_u64(n: u64) -> bool {
|
||||||
|
let n = 2 * n + 1;
|
||||||
|
modular_inverse(n).wrapping_mul(n) == 1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue