1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +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:
nicoo 2020-08-03 14:00:34 +02:00 committed by GitHub
parent 70828329ba
commit 34a5941ee9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 4 deletions

View file

@ -51,7 +51,7 @@ mod tests {
use quickcheck::quickcheck;
quickcheck! {
fn gcd(a: u64, b: u64) -> bool {
fn euclidean(a: u64, b: u64) -> bool {
// Test against the Euclidean algorithm
let g = {
let (mut a, mut b) = (a, b);
@ -61,7 +61,38 @@ mod tests {
}
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)
}
}
}

View file

@ -47,8 +47,9 @@ pub(crate) fn modular_inverse<T: Int>(a: T) -> T {
mod tests {
use super::{super::traits::Int, *};
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
let one = T::from(1).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));
}
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
}
}
}