Now with tests for the basic algorithms.

This commit is contained in:
2018-09-28 17:48:35 -05:00
parent 3b68363b49
commit 304d009a67
95 changed files with 271012 additions and 270361 deletions

View File

@@ -4,3 +4,4 @@ version = "0.1.0"
authors = ["awick"] authors = ["awick"]
[dependencies] [dependencies]
quickcheck = "0.7.1"

View File

@@ -51,15 +51,20 @@ conversions :: [Int] -> [(Int,Int)]
conversions [] = [] conversions [] = []
conversions (x:rest) = (map (\ y -> (x,y)) rest) ++ conversions rest conversions (x:rest) = (map (\ y -> (x,y)) rest) ++ conversions rest
generateTestBlock :: Handle -> String -> IO () generateTestBlock :: Handle -> String -> Level -> Bool -> [Int -> Int] -> IO ()
generateTestBlock hndl name = generateTestBlock hndl name level useRT addOns =
do hPutStrLn hndl (" mod " ++ name ++ " {") do hPutStrLn hndl (" mod " ++ name ++ " {")
hPutStrLn hndl (" use super::super::*;\n") when useRT $
hPutStrLn hndl (" use testing::run_test;\n") do hPutStrLn hndl (" use super::super::*;")
hPutStrLn hndl (" use testing::run_test;")
hPutStrLn hndl ""
forM_ (sort (Map.toList finalMap)) $ \ (size, kind) -> forM_ (sort (Map.toList finalMap)) $ \ (size, kind) ->
when (kind >= Base) $ when (kind >= level) $
hPutStrLn hndl (" generate_" ++ name ++ hPutStrLn hndl (" generate_" ++ name ++
"_tests!(U" ++ show size ++ ");") "_tests!(U" ++ show size ++ ", " ++
"u" ++ show size ++
concatMap (\ f -> ", U" ++ show (f size)) addOns ++
");")
hPutStrLn hndl " }" hPutStrLn hndl " }"
generateInvocs :: IO () generateInvocs :: IO ()
@@ -88,7 +93,16 @@ generateInvocs =
"U" ++ show b ++ ");") "U" ++ show b ++ ");")
hPutStrLn hndl "\n#[cfg(test)]" hPutStrLn hndl "\n#[cfg(test)]"
hPutStrLn hndl "mod tests {" hPutStrLn hndl "mod tests {"
generateTestBlock hndl "base" generateTestBlock hndl "base" Base True []
generateTestBlock hndl "conversion" Base False []
generateTestBlock hndl "codec" Base False []
generateTestBlock hndl "cmp" Base True []
generateTestBlock hndl "sub" Base True []
generateTestBlock hndl "shiftl" Base True []
generateTestBlock hndl "shiftr" Base True []
generateTestBlock hndl "add" DivMul True [(+ 64)]
generateTestBlock hndl "mul" DivMul True [(* 2)]
generateTestBlock hndl "div" DivMul True []
hPutStrLn hndl "}" hPutStrLn hndl "}"
log :: String -> IO () log :: String -> IO ()
@@ -160,8 +174,8 @@ generateAllTheTests =
generateTests DivMul "add" db1 $ \ size memory0 -> generateTests DivMul "add" db1 $ \ size memory0 ->
let (a, memory1) = generateNum memory0 "a" size let (a, memory1) = generateNum memory0 "a" size
(b, memory2) = generateNum memory1 "b" size (b, memory2) = generateNum memory1 "b" size
c = modulate (a + b) size c = a + b
in (Map.fromList [("a", showX a), ("b", showX b), ("c", showX c)], memory2) in (Map.fromList [("a", showX a), ("b", showX b),("c", showX c)], memory2)
let (db2, gen2) = emptyDatabase gen1 let (db2, gen2) = emptyDatabase gen1
generateTests Barrett "barrett_gen" db2 $ \ size memory0 -> generateTests Barrett "barrett_gen" db2 $ \ size memory0 ->
let (m, memory1) = generateNum memory0 "m" size let (m, memory1) = generateNum memory0 "m" size
@@ -201,16 +215,18 @@ generateAllTheTests =
generateTests DivMul "div" db6 $ \ size memory0 -> generateTests DivMul "div" db6 $ \ size memory0 ->
let (a, memory1) = generateNum memory0 "a" size let (a, memory1) = generateNum memory0 "a" size
(b, memory2) = generateNum memory1 "b" size (b, memory2) = generateNum memory1 "b" size
res = Map.fromList [("a", showX a), ("b", showX b), ("c", showX (a `div` b))] q = a `div` b
r = a `mod` b
res = Map.fromList [("a", showX a), ("b", showX b),
("q", showX q), ("r", showX r)]
in (res, memory2) in (res, memory2)
let (db7, gen7) = emptyDatabase gen5 let (db7, gen7) = emptyDatabase gen5
generateTests DivMul "mul" db7 $ \ size memory0 -> generateTests DivMul "mul" db7 $ \ size memory0 ->
let (a, memory1) = generateNum memory0 "a" size let (a, memory1) = generateNum memory0 "a" size
(b, memory2) = generateNum memory1 "b" size (b, memory2) = generateNum memory1 "b" size
c = a * b c = a * b
d = modulate c size
res = Map.fromList [("a", showX a), ("b", showX b), res = Map.fromList [("a", showX a), ("b", showX b),
("c", showX c), ("d", showX d)] ("c", showX c)]
in (res, memory2) in (res, memory2)
let (db8, gen8) = emptyDatabase gen6 let (db8, gen8) = emptyDatabase gen6
generateTests Base "shiftl" db8 $ \ size memory0 -> generateTests Base "shiftl" db8 $ \ size memory0 ->

View File

@@ -1,4 +1,9 @@
#![recursion_limit="1024"] #![recursion_limit="1024"]
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
pub mod unsigned; pub mod unsigned;
#[cfg(test)] #[cfg(test)]
pub mod testing; pub mod testing;

View File

@@ -14,7 +14,7 @@ pub fn addition(dest: &mut [u64], src: &[u64])
dest[src.len()] = carry as u64; dest[src.len()] = carry as u64;
} }
pub fn unsafe_addition(dest: &mut [u64], src: &[u64]) pub fn unsafe_addition(dest: &mut [u64], src: &[u64], really_unsafe: bool)
{ {
assert_eq!(dest.len(), src.len()); assert_eq!(dest.len(), src.len());
let mut carry: u128 = 0; let mut carry: u128 = 0;
@@ -27,7 +27,10 @@ pub fn unsafe_addition(dest: &mut [u64], src: &[u64])
dest[i] = z128 as u64; dest[i] = z128 as u64;
carry = z128 >> 64; carry = z128 >> 64;
} }
if !really_unsafe {
assert_eq!(carry, 0, "Unsafe overflow in AddAssign"); assert_eq!(carry, 0, "Unsafe overflow in AddAssign");
}
} }
macro_rules! addition_impls macro_rules! addition_impls
@@ -35,13 +38,13 @@ macro_rules! addition_impls
($base: ident, $bigger: ident) => { ($base: ident, $bigger: ident) => {
impl AddAssign<$base> for $base { impl AddAssign<$base> for $base {
fn add_assign(&mut self, rhs: $base) { fn add_assign(&mut self, rhs: $base) {
unsafe_addition(&mut self.value, &rhs.value); unsafe_addition(&mut self.value, &rhs.value, false);
} }
} }
impl<'a> AddAssign<&'a $base> for $base { impl<'a> AddAssign<&'a $base> for $base {
fn add_assign(&mut self, rhs: &$base) { fn add_assign(&mut self, rhs: &$base) {
unsafe_addition(&mut self.value, &rhs.value); unsafe_addition(&mut self.value, &rhs.value, false);
} }
} }
@@ -95,4 +98,29 @@ macro_rules! addition_impls
} }
} }
//addition_impls!(U192, U256); #[cfg(test)]
macro_rules! generate_add_tests {
($name: ident, $lname: ident, $plus1: ident) => {
#[test]
fn $lname() {
let fname = format!("testdata/add/{}.tests", stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let c = $plus1::from_bytes(cbytes);
assert_eq!(c, &a + &b);
if c.value[c.value.len()-1] == 0 {
let mut aprime = a.clone();
aprime += b;
assert_eq!($name::from(c), aprime);
}
});
}
};
}

View File

@@ -38,13 +38,20 @@ macro_rules! generate_base
} }
} }
} }
}
}
#[cfg(test)] #[cfg(test)]
macro_rules! generate_base_tests impl Arbitrary for $name {
{ fn arbitrary<G: Gen>(g: &mut G) -> $name {
($name: ident) => { let mut res = $name::zero();
for val in res.value.iter_mut() {
*val = g.next_u64();
}
res
}
}
#[cfg(test)]
impl fmt::Debug for $name { impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(stringify!($name))?; f.write_str(stringify!($name))?;
@@ -53,10 +60,15 @@ macro_rules! generate_base_tests
f.write_str("}") f.write_str("}")
} }
} }
}
}
#[cfg(test)]
macro_rules! generate_base_tests
{
($name: ident, $lname: ident) => {
#[test] #[test]
#[allow(non_snake_case)] fn $lname() {
fn $name() {
let fname = format!("testdata/base/{}.tests", stringify!($name)); let fname = format!("testdata/base/{}.tests", stringify!($name));
run_test(fname.to_string(), 6, |case| { run_test(fname.to_string(), 6, |case| {
let (neg0, xbytes) = case.get("x").unwrap(); let (neg0, xbytes) = case.get("x").unwrap();

View File

@@ -40,3 +40,33 @@ macro_rules! cmp_impls {
} }
} }
} }
#[cfg(test)]
macro_rules! generate_cmp_tests {
($name: ident, $lname: ident) => {
#[test]
fn $lname() {
let fname = format!("testdata/cmp/{}.tests", stringify!($name));
run_test(fname.to_string(), 5, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, ebytes) = case.get("e").unwrap();
let (neg3, gbytes) = case.get("g").unwrap();
let (neg4, lbytes) = case.get("l").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let e = 1 == ebytes[0];
let g = 1 == gbytes[0];
let l = 1 == lbytes[0];
assert_eq!(e, a == b);
assert_eq!(g, a > b);
assert_eq!(l, a < b);
assert_eq!(e || g, a >= b);
assert_eq!(e || l, a <= b);
});
}
};
}

View File

@@ -68,3 +68,21 @@ macro_rules! generate_codec
generate_encoder!($name); generate_encoder!($name);
} }
} }
#[cfg(test)]
macro_rules! generate_codec_tests {
($name: ident, $lname: ident) => {
#[cfg(test)]
mod $lname {
use super::super::super::*;
quickcheck! {
fn decode_encode(x: $name) -> bool {
let bytes = x.to_bytes();
let x2 = $name::from_bytes(&bytes);
x == x2
}
}
}
};
}

View File

@@ -19,6 +19,26 @@ macro_rules! generate_base_conversions
() => {}; () => {};
} }
#[cfg(test)]
macro_rules! generate_conversion_tests
{
($name: ident, $lname: ident) => {
#[cfg(test)]
mod $lname {
use super::super::super::*;
use std::convert::From;
quickcheck! {
fn conversion_u8( x: u8) -> bool { x == u8::from($name::from(x)) }
fn conversion_u16( x: u16) -> bool { x == u16::from($name::from(x)) }
fn conversion_u32( x: u32) -> bool { x == u32::from($name::from(x)) }
fn conversion_u64( x: u64) -> bool { x == u64::from($name::from(x)) }
fn conversion_usize(x: usize) -> bool { x == usize::from($name::from(x)) }
}
}
}
}
macro_rules! conversion_impls macro_rules! conversion_impls
{ {
($name: ident, $other: ident) => { ($name: ident, $other: ident) => {

View File

@@ -220,3 +220,28 @@ macro_rules! div_impls
} }
} }
} }
#[cfg(test)]
macro_rules! generate_div_tests {
($name: ident, $lname: ident) => {
#[test]
fn $lname() {
let fname = format!("testdata/div/{}.tests", stringify!($name));
run_test(fname.to_string(), 4, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, qbytes) = case.get("q").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let q = $name::from_bytes(qbytes);
let r = $name::from_bytes(rbytes);
let (myq, myr) = a.divmod(&b);
assert_eq!(q, myq);
assert_eq!(r, myr);
});
}
};
}

View File

@@ -1229,57 +1229,470 @@ conversion_impls!(U32896, U61568);
mod tests { mod tests {
mod base { mod base {
use super::super::*; use super::super::*;
use testing::run_test; use testing::run_test;
generate_base_tests!(U192); generate_base_tests!(U192, u192);
generate_base_tests!(U256); generate_base_tests!(U256, u256);
generate_base_tests!(U320); generate_base_tests!(U320, u320);
generate_base_tests!(U384); generate_base_tests!(U384, u384);
generate_base_tests!(U448); generate_base_tests!(U448, u448);
generate_base_tests!(U512); generate_base_tests!(U512, u512);
generate_base_tests!(U576); generate_base_tests!(U576, u576);
generate_base_tests!(U640); generate_base_tests!(U640, u640);
generate_base_tests!(U704); generate_base_tests!(U704, u704);
generate_base_tests!(U768); generate_base_tests!(U768, u768);
generate_base_tests!(U832); generate_base_tests!(U832, u832);
generate_base_tests!(U896); generate_base_tests!(U896, u896);
generate_base_tests!(U1024); generate_base_tests!(U1024, u1024);
generate_base_tests!(U1088); generate_base_tests!(U1088, u1088);
generate_base_tests!(U1152); generate_base_tests!(U1152, u1152);
generate_base_tests!(U1216); generate_base_tests!(U1216, u1216);
generate_base_tests!(U1280); generate_base_tests!(U1280, u1280);
generate_base_tests!(U1664); generate_base_tests!(U1664, u1664);
generate_base_tests!(U2048); generate_base_tests!(U2048, u2048);
generate_base_tests!(U2112); generate_base_tests!(U2112, u2112);
generate_base_tests!(U2176); generate_base_tests!(U2176, u2176);
generate_base_tests!(U2432); generate_base_tests!(U2432, u2432);
generate_base_tests!(U3072); generate_base_tests!(U3072, u3072);
generate_base_tests!(U3136); generate_base_tests!(U3136, u3136);
generate_base_tests!(U3200); generate_base_tests!(U3200, u3200);
generate_base_tests!(U4096); generate_base_tests!(U4096, u4096);
generate_base_tests!(U4160); generate_base_tests!(U4160, u4160);
generate_base_tests!(U4224); generate_base_tests!(U4224, u4224);
generate_base_tests!(U6144); generate_base_tests!(U6144, u6144);
generate_base_tests!(U6208); generate_base_tests!(U6208, u6208);
generate_base_tests!(U6272); generate_base_tests!(U6272, u6272);
generate_base_tests!(U7680); generate_base_tests!(U7680, u7680);
generate_base_tests!(U7744); generate_base_tests!(U7744, u7744);
generate_base_tests!(U7808); generate_base_tests!(U7808, u7808);
generate_base_tests!(U8192); generate_base_tests!(U8192, u8192);
generate_base_tests!(U8256); generate_base_tests!(U8256, u8256);
generate_base_tests!(U8320); generate_base_tests!(U8320, u8320);
generate_base_tests!(U12416); generate_base_tests!(U12416, u12416);
generate_base_tests!(U15360); generate_base_tests!(U15360, u15360);
generate_base_tests!(U15424); generate_base_tests!(U15424, u15424);
generate_base_tests!(U15488); generate_base_tests!(U15488, u15488);
generate_base_tests!(U16384); generate_base_tests!(U16384, u16384);
generate_base_tests!(U16448); generate_base_tests!(U16448, u16448);
generate_base_tests!(U16512); generate_base_tests!(U16512, u16512);
generate_base_tests!(U30720); generate_base_tests!(U30720, u30720);
generate_base_tests!(U30784); generate_base_tests!(U30784, u30784);
generate_base_tests!(U30848); generate_base_tests!(U30848, u30848);
generate_base_tests!(U32896); generate_base_tests!(U32896, u32896);
generate_base_tests!(U61568); generate_base_tests!(U61568, u61568);
}
mod conversion {
generate_conversion_tests!(U192, u192);
generate_conversion_tests!(U256, u256);
generate_conversion_tests!(U320, u320);
generate_conversion_tests!(U384, u384);
generate_conversion_tests!(U448, u448);
generate_conversion_tests!(U512, u512);
generate_conversion_tests!(U576, u576);
generate_conversion_tests!(U640, u640);
generate_conversion_tests!(U704, u704);
generate_conversion_tests!(U768, u768);
generate_conversion_tests!(U832, u832);
generate_conversion_tests!(U896, u896);
generate_conversion_tests!(U1024, u1024);
generate_conversion_tests!(U1088, u1088);
generate_conversion_tests!(U1152, u1152);
generate_conversion_tests!(U1216, u1216);
generate_conversion_tests!(U1280, u1280);
generate_conversion_tests!(U1664, u1664);
generate_conversion_tests!(U2048, u2048);
generate_conversion_tests!(U2112, u2112);
generate_conversion_tests!(U2176, u2176);
generate_conversion_tests!(U2432, u2432);
generate_conversion_tests!(U3072, u3072);
generate_conversion_tests!(U3136, u3136);
generate_conversion_tests!(U3200, u3200);
generate_conversion_tests!(U4096, u4096);
generate_conversion_tests!(U4160, u4160);
generate_conversion_tests!(U4224, u4224);
generate_conversion_tests!(U6144, u6144);
generate_conversion_tests!(U6208, u6208);
generate_conversion_tests!(U6272, u6272);
generate_conversion_tests!(U7680, u7680);
generate_conversion_tests!(U7744, u7744);
generate_conversion_tests!(U7808, u7808);
generate_conversion_tests!(U8192, u8192);
generate_conversion_tests!(U8256, u8256);
generate_conversion_tests!(U8320, u8320);
generate_conversion_tests!(U12416, u12416);
generate_conversion_tests!(U15360, u15360);
generate_conversion_tests!(U15424, u15424);
generate_conversion_tests!(U15488, u15488);
generate_conversion_tests!(U16384, u16384);
generate_conversion_tests!(U16448, u16448);
generate_conversion_tests!(U16512, u16512);
generate_conversion_tests!(U30720, u30720);
generate_conversion_tests!(U30784, u30784);
generate_conversion_tests!(U30848, u30848);
generate_conversion_tests!(U32896, u32896);
generate_conversion_tests!(U61568, u61568);
}
mod codec {
generate_codec_tests!(U192, u192);
generate_codec_tests!(U256, u256);
generate_codec_tests!(U320, u320);
generate_codec_tests!(U384, u384);
generate_codec_tests!(U448, u448);
generate_codec_tests!(U512, u512);
generate_codec_tests!(U576, u576);
generate_codec_tests!(U640, u640);
generate_codec_tests!(U704, u704);
generate_codec_tests!(U768, u768);
generate_codec_tests!(U832, u832);
generate_codec_tests!(U896, u896);
generate_codec_tests!(U1024, u1024);
generate_codec_tests!(U1088, u1088);
generate_codec_tests!(U1152, u1152);
generate_codec_tests!(U1216, u1216);
generate_codec_tests!(U1280, u1280);
generate_codec_tests!(U1664, u1664);
generate_codec_tests!(U2048, u2048);
generate_codec_tests!(U2112, u2112);
generate_codec_tests!(U2176, u2176);
generate_codec_tests!(U2432, u2432);
generate_codec_tests!(U3072, u3072);
generate_codec_tests!(U3136, u3136);
generate_codec_tests!(U3200, u3200);
generate_codec_tests!(U4096, u4096);
generate_codec_tests!(U4160, u4160);
generate_codec_tests!(U4224, u4224);
generate_codec_tests!(U6144, u6144);
generate_codec_tests!(U6208, u6208);
generate_codec_tests!(U6272, u6272);
generate_codec_tests!(U7680, u7680);
generate_codec_tests!(U7744, u7744);
generate_codec_tests!(U7808, u7808);
generate_codec_tests!(U8192, u8192);
generate_codec_tests!(U8256, u8256);
generate_codec_tests!(U8320, u8320);
generate_codec_tests!(U12416, u12416);
generate_codec_tests!(U15360, u15360);
generate_codec_tests!(U15424, u15424);
generate_codec_tests!(U15488, u15488);
generate_codec_tests!(U16384, u16384);
generate_codec_tests!(U16448, u16448);
generate_codec_tests!(U16512, u16512);
generate_codec_tests!(U30720, u30720);
generate_codec_tests!(U30784, u30784);
generate_codec_tests!(U30848, u30848);
generate_codec_tests!(U32896, u32896);
generate_codec_tests!(U61568, u61568);
}
mod cmp {
use super::super::*;
use testing::run_test;
generate_cmp_tests!(U192, u192);
generate_cmp_tests!(U256, u256);
generate_cmp_tests!(U320, u320);
generate_cmp_tests!(U384, u384);
generate_cmp_tests!(U448, u448);
generate_cmp_tests!(U512, u512);
generate_cmp_tests!(U576, u576);
generate_cmp_tests!(U640, u640);
generate_cmp_tests!(U704, u704);
generate_cmp_tests!(U768, u768);
generate_cmp_tests!(U832, u832);
generate_cmp_tests!(U896, u896);
generate_cmp_tests!(U1024, u1024);
generate_cmp_tests!(U1088, u1088);
generate_cmp_tests!(U1152, u1152);
generate_cmp_tests!(U1216, u1216);
generate_cmp_tests!(U1280, u1280);
generate_cmp_tests!(U1664, u1664);
generate_cmp_tests!(U2048, u2048);
generate_cmp_tests!(U2112, u2112);
generate_cmp_tests!(U2176, u2176);
generate_cmp_tests!(U2432, u2432);
generate_cmp_tests!(U3072, u3072);
generate_cmp_tests!(U3136, u3136);
generate_cmp_tests!(U3200, u3200);
generate_cmp_tests!(U4096, u4096);
generate_cmp_tests!(U4160, u4160);
generate_cmp_tests!(U4224, u4224);
generate_cmp_tests!(U6144, u6144);
generate_cmp_tests!(U6208, u6208);
generate_cmp_tests!(U6272, u6272);
generate_cmp_tests!(U7680, u7680);
generate_cmp_tests!(U7744, u7744);
generate_cmp_tests!(U7808, u7808);
generate_cmp_tests!(U8192, u8192);
generate_cmp_tests!(U8256, u8256);
generate_cmp_tests!(U8320, u8320);
generate_cmp_tests!(U12416, u12416);
generate_cmp_tests!(U15360, u15360);
generate_cmp_tests!(U15424, u15424);
generate_cmp_tests!(U15488, u15488);
generate_cmp_tests!(U16384, u16384);
generate_cmp_tests!(U16448, u16448);
generate_cmp_tests!(U16512, u16512);
generate_cmp_tests!(U30720, u30720);
generate_cmp_tests!(U30784, u30784);
generate_cmp_tests!(U30848, u30848);
generate_cmp_tests!(U32896, u32896);
generate_cmp_tests!(U61568, u61568);
}
mod sub {
use super::super::*;
use testing::run_test;
generate_sub_tests!(U192, u192);
generate_sub_tests!(U256, u256);
generate_sub_tests!(U320, u320);
generate_sub_tests!(U384, u384);
generate_sub_tests!(U448, u448);
generate_sub_tests!(U512, u512);
generate_sub_tests!(U576, u576);
generate_sub_tests!(U640, u640);
generate_sub_tests!(U704, u704);
generate_sub_tests!(U768, u768);
generate_sub_tests!(U832, u832);
generate_sub_tests!(U896, u896);
generate_sub_tests!(U1024, u1024);
generate_sub_tests!(U1088, u1088);
generate_sub_tests!(U1152, u1152);
generate_sub_tests!(U1216, u1216);
generate_sub_tests!(U1280, u1280);
generate_sub_tests!(U1664, u1664);
generate_sub_tests!(U2048, u2048);
generate_sub_tests!(U2112, u2112);
generate_sub_tests!(U2176, u2176);
generate_sub_tests!(U2432, u2432);
generate_sub_tests!(U3072, u3072);
generate_sub_tests!(U3136, u3136);
generate_sub_tests!(U3200, u3200);
generate_sub_tests!(U4096, u4096);
generate_sub_tests!(U4160, u4160);
generate_sub_tests!(U4224, u4224);
generate_sub_tests!(U6144, u6144);
generate_sub_tests!(U6208, u6208);
generate_sub_tests!(U6272, u6272);
generate_sub_tests!(U7680, u7680);
generate_sub_tests!(U7744, u7744);
generate_sub_tests!(U7808, u7808);
generate_sub_tests!(U8192, u8192);
generate_sub_tests!(U8256, u8256);
generate_sub_tests!(U8320, u8320);
generate_sub_tests!(U12416, u12416);
generate_sub_tests!(U15360, u15360);
generate_sub_tests!(U15424, u15424);
generate_sub_tests!(U15488, u15488);
generate_sub_tests!(U16384, u16384);
generate_sub_tests!(U16448, u16448);
generate_sub_tests!(U16512, u16512);
generate_sub_tests!(U30720, u30720);
generate_sub_tests!(U30784, u30784);
generate_sub_tests!(U30848, u30848);
generate_sub_tests!(U32896, u32896);
generate_sub_tests!(U61568, u61568);
}
mod shiftl {
use super::super::*;
use testing::run_test;
generate_shiftl_tests!(U192, u192);
generate_shiftl_tests!(U256, u256);
generate_shiftl_tests!(U320, u320);
generate_shiftl_tests!(U384, u384);
generate_shiftl_tests!(U448, u448);
generate_shiftl_tests!(U512, u512);
generate_shiftl_tests!(U576, u576);
generate_shiftl_tests!(U640, u640);
generate_shiftl_tests!(U704, u704);
generate_shiftl_tests!(U768, u768);
generate_shiftl_tests!(U832, u832);
generate_shiftl_tests!(U896, u896);
generate_shiftl_tests!(U1024, u1024);
generate_shiftl_tests!(U1088, u1088);
generate_shiftl_tests!(U1152, u1152);
generate_shiftl_tests!(U1216, u1216);
generate_shiftl_tests!(U1280, u1280);
generate_shiftl_tests!(U1664, u1664);
generate_shiftl_tests!(U2048, u2048);
generate_shiftl_tests!(U2112, u2112);
generate_shiftl_tests!(U2176, u2176);
generate_shiftl_tests!(U2432, u2432);
generate_shiftl_tests!(U3072, u3072);
generate_shiftl_tests!(U3136, u3136);
generate_shiftl_tests!(U3200, u3200);
generate_shiftl_tests!(U4096, u4096);
generate_shiftl_tests!(U4160, u4160);
generate_shiftl_tests!(U4224, u4224);
generate_shiftl_tests!(U6144, u6144);
generate_shiftl_tests!(U6208, u6208);
generate_shiftl_tests!(U6272, u6272);
generate_shiftl_tests!(U7680, u7680);
generate_shiftl_tests!(U7744, u7744);
generate_shiftl_tests!(U7808, u7808);
generate_shiftl_tests!(U8192, u8192);
generate_shiftl_tests!(U8256, u8256);
generate_shiftl_tests!(U8320, u8320);
generate_shiftl_tests!(U12416, u12416);
generate_shiftl_tests!(U15360, u15360);
generate_shiftl_tests!(U15424, u15424);
generate_shiftl_tests!(U15488, u15488);
generate_shiftl_tests!(U16384, u16384);
generate_shiftl_tests!(U16448, u16448);
generate_shiftl_tests!(U16512, u16512);
generate_shiftl_tests!(U30720, u30720);
generate_shiftl_tests!(U30784, u30784);
generate_shiftl_tests!(U30848, u30848);
generate_shiftl_tests!(U32896, u32896);
generate_shiftl_tests!(U61568, u61568);
}
mod shiftr {
use super::super::*;
use testing::run_test;
generate_shiftr_tests!(U192, u192);
generate_shiftr_tests!(U256, u256);
generate_shiftr_tests!(U320, u320);
generate_shiftr_tests!(U384, u384);
generate_shiftr_tests!(U448, u448);
generate_shiftr_tests!(U512, u512);
generate_shiftr_tests!(U576, u576);
generate_shiftr_tests!(U640, u640);
generate_shiftr_tests!(U704, u704);
generate_shiftr_tests!(U768, u768);
generate_shiftr_tests!(U832, u832);
generate_shiftr_tests!(U896, u896);
generate_shiftr_tests!(U1024, u1024);
generate_shiftr_tests!(U1088, u1088);
generate_shiftr_tests!(U1152, u1152);
generate_shiftr_tests!(U1216, u1216);
generate_shiftr_tests!(U1280, u1280);
generate_shiftr_tests!(U1664, u1664);
generate_shiftr_tests!(U2048, u2048);
generate_shiftr_tests!(U2112, u2112);
generate_shiftr_tests!(U2176, u2176);
generate_shiftr_tests!(U2432, u2432);
generate_shiftr_tests!(U3072, u3072);
generate_shiftr_tests!(U3136, u3136);
generate_shiftr_tests!(U3200, u3200);
generate_shiftr_tests!(U4096, u4096);
generate_shiftr_tests!(U4160, u4160);
generate_shiftr_tests!(U4224, u4224);
generate_shiftr_tests!(U6144, u6144);
generate_shiftr_tests!(U6208, u6208);
generate_shiftr_tests!(U6272, u6272);
generate_shiftr_tests!(U7680, u7680);
generate_shiftr_tests!(U7744, u7744);
generate_shiftr_tests!(U7808, u7808);
generate_shiftr_tests!(U8192, u8192);
generate_shiftr_tests!(U8256, u8256);
generate_shiftr_tests!(U8320, u8320);
generate_shiftr_tests!(U12416, u12416);
generate_shiftr_tests!(U15360, u15360);
generate_shiftr_tests!(U15424, u15424);
generate_shiftr_tests!(U15488, u15488);
generate_shiftr_tests!(U16384, u16384);
generate_shiftr_tests!(U16448, u16448);
generate_shiftr_tests!(U16512, u16512);
generate_shiftr_tests!(U30720, u30720);
generate_shiftr_tests!(U30784, u30784);
generate_shiftr_tests!(U30848, u30848);
generate_shiftr_tests!(U32896, u32896);
generate_shiftr_tests!(U61568, u61568);
}
mod add {
use super::super::*;
use testing::run_test;
generate_add_tests!(U192, u192, U256);
generate_add_tests!(U256, u256, U320);
generate_add_tests!(U320, u320, U384);
generate_add_tests!(U384, u384, U448);
generate_add_tests!(U448, u448, U512);
generate_add_tests!(U512, u512, U576);
generate_add_tests!(U576, u576, U640);
generate_add_tests!(U640, u640, U704);
generate_add_tests!(U832, u832, U896);
generate_add_tests!(U1024, u1024, U1088);
generate_add_tests!(U1088, u1088, U1152);
generate_add_tests!(U1216, u1216, U1280);
generate_add_tests!(U2048, u2048, U2112);
generate_add_tests!(U2112, u2112, U2176);
generate_add_tests!(U3072, u3072, U3136);
generate_add_tests!(U3136, u3136, U3200);
generate_add_tests!(U4096, u4096, U4160);
generate_add_tests!(U4160, u4160, U4224);
generate_add_tests!(U6208, u6208, U6272);
generate_add_tests!(U7680, u7680, U7744);
generate_add_tests!(U7744, u7744, U7808);
generate_add_tests!(U8192, u8192, U8256);
generate_add_tests!(U8256, u8256, U8320);
generate_add_tests!(U15360, u15360, U15424);
generate_add_tests!(U15424, u15424, U15488);
generate_add_tests!(U16448, u16448, U16512);
generate_add_tests!(U30784, u30784, U30848);
}
mod mul {
use super::super::*;
use testing::run_test;
generate_mul_tests!(U192, u192, U384);
generate_mul_tests!(U256, u256, U512);
generate_mul_tests!(U320, u320, U640);
generate_mul_tests!(U384, u384, U768);
generate_mul_tests!(U448, u448, U896);
generate_mul_tests!(U512, u512, U1024);
generate_mul_tests!(U576, u576, U1152);
generate_mul_tests!(U640, u640, U1280);
generate_mul_tests!(U832, u832, U1664);
generate_mul_tests!(U1024, u1024, U2048);
generate_mul_tests!(U1088, u1088, U2176);
generate_mul_tests!(U1216, u1216, U2432);
generate_mul_tests!(U2048, u2048, U4096);
generate_mul_tests!(U2112, u2112, U4224);
generate_mul_tests!(U3072, u3072, U6144);
generate_mul_tests!(U3136, u3136, U6272);
generate_mul_tests!(U4096, u4096, U8192);
generate_mul_tests!(U4160, u4160, U8320);
generate_mul_tests!(U6208, u6208, U12416);
generate_mul_tests!(U7680, u7680, U15360);
generate_mul_tests!(U7744, u7744, U15488);
generate_mul_tests!(U8192, u8192, U16384);
generate_mul_tests!(U8256, u8256, U16512);
generate_mul_tests!(U15360, u15360, U30720);
generate_mul_tests!(U15424, u15424, U30848);
generate_mul_tests!(U16448, u16448, U32896);
generate_mul_tests!(U30784, u30784, U61568);
}
mod div {
use super::super::*;
use testing::run_test;
generate_div_tests!(U192, u192);
generate_div_tests!(U256, u256);
generate_div_tests!(U320, u320);
generate_div_tests!(U384, u384);
generate_div_tests!(U448, u448);
generate_div_tests!(U512, u512);
generate_div_tests!(U576, u576);
generate_div_tests!(U640, u640);
generate_div_tests!(U832, u832);
generate_div_tests!(U1024, u1024);
generate_div_tests!(U1088, u1088);
generate_div_tests!(U1216, u1216);
generate_div_tests!(U2048, u2048);
generate_div_tests!(U2112, u2112);
generate_div_tests!(U3072, u3072);
generate_div_tests!(U3136, u3136);
generate_div_tests!(U4096, u4096);
generate_div_tests!(U4160, u4160);
generate_div_tests!(U6208, u6208);
generate_div_tests!(U7680, u7680);
generate_div_tests!(U7744, u7744);
generate_div_tests!(U8192, u8192);
generate_div_tests!(U8256, u8256);
generate_div_tests!(U15360, u15360);
generate_div_tests!(U15424, u15424);
generate_div_tests!(U16448, u16448);
generate_div_tests!(U30784, u30784);
} }
} }

View File

@@ -35,6 +35,8 @@ use std::ops::{Sub,SubAssign};
#[cfg(test)] #[cfg(test)]
use std::fmt; use std::fmt;
#[cfg(test)]
use quickcheck::{Arbitrary,Gen};
macro_rules! generate_number macro_rules! generate_number
{ {

View File

@@ -63,3 +63,25 @@ macro_rules! multiply_impls {
} }
}; };
} }
#[cfg(test)]
macro_rules! generate_mul_tests
{
($name: ident, $lname: ident, $dbl: ident) => {
#[test]
fn $lname() {
let fname = format!("testdata/mul/{}.tests", stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let c = $dbl::from_bytes(cbytes);
assert_eq!(c, &a * &b);
});
}
};
}

View File

@@ -89,4 +89,44 @@ macro_rules! shift_impls
} }
} }
//shift_impls!(U192, 3); #[cfg(test)]
macro_rules! generate_shiftl_tests {
($name: ident, $lname: ident) => {
#[test]
fn $lname() {
let fname = format!("testdata/shiftl/{}.tests", stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, lbytes) = case.get("l").unwrap();
let (neg2, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let l = $name::from_bytes(lbytes);
let r = $name::from_bytes(rbytes);
assert_eq!(r, a << usize::from(l));
});
}
};
}
#[cfg(test)]
macro_rules! generate_shiftr_tests {
($name: ident, $lname: ident) => {
#[test]
fn $lname() {
let fname = format!("testdata/shiftr/{}.tests", stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, lbytes) = case.get("l").unwrap();
let (neg2, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let l = $name::from_bytes(lbytes);
let r = $name::from_bytes(rbytes);
assert_eq!(r, a >> usize::from(l));
});
}
};
}

View File

@@ -1,13 +1,13 @@
use unsigned::add::unsafe_addition; use unsigned::add::unsafe_addition;
pub fn subtract(res: &mut [u64], spare: &mut [u64], other: &[u64]) pub fn subtract(res: &mut [u64], spare: &mut [u64], other: &mut [u64])
{ {
for i in 0..res.len() { for i in 0..res.len() {
res[i] = !res[i]; other[i] = !other[i];
} }
spare[0] = 1; spare[0] = 1;
unsafe_addition(res, &spare); unsafe_addition(other, &spare, true);
unsafe_addition(res, &other); unsafe_addition(res, &other, true);
} }
macro_rules! subtraction_impls macro_rules! subtraction_impls
@@ -16,14 +16,14 @@ macro_rules! subtraction_impls
impl SubAssign for $name { impl SubAssign for $name {
fn sub_assign(&mut self, rhs: $name) { fn sub_assign(&mut self, rhs: $name) {
let mut temp = [0; $size]; let mut temp = [0; $size];
subtract(&mut self.value, &mut temp, &rhs.value); subtract(&mut self.value, &mut temp, &mut rhs.value.clone());
} }
} }
impl<'a> SubAssign<&'a $name> for $name { impl<'a> SubAssign<&'a $name> for $name {
fn sub_assign(&mut self, rhs: &$name) { fn sub_assign(&mut self, rhs: &$name) {
let mut temp = [0; $size]; let mut temp = [0; $size];
subtract(&mut self.value, &mut temp, &rhs.value); subtract(&mut self.value, &mut temp, &mut rhs.value.clone());
} }
} }
@@ -31,9 +31,9 @@ macro_rules! subtraction_impls
type Output = $name; type Output = $name;
fn sub(self, rhs: $name) -> $name { fn sub(self, rhs: $name) -> $name {
let mut res = $name::zero(); let mut res = self.clone();
let mut temp = [0; $size]; let mut temp = [0; $size];
subtract(&mut res.value, &mut temp, &rhs.value); subtract(&mut res.value, &mut temp, &mut rhs.value.clone());
res res
} }
} }
@@ -42,9 +42,9 @@ macro_rules! subtraction_impls
type Output = $name; type Output = $name;
fn sub(self, rhs: $name) -> $name { fn sub(self, rhs: $name) -> $name {
let mut res = $name::zero(); let mut res = self.clone();
let mut temp = [0; $size]; let mut temp = [0; $size];
subtract(&mut res.value, &mut temp, &rhs.value); subtract(&mut res.value, &mut temp, &mut rhs.value.clone());
res res
} }
} }
@@ -53,9 +53,9 @@ macro_rules! subtraction_impls
type Output = $name; type Output = $name;
fn sub(self, rhs: &$name) -> $name { fn sub(self, rhs: &$name) -> $name {
let mut res = $name::zero(); let mut res = self.clone();
let mut temp = [0; $size]; let mut temp = [0; $size];
subtract(&mut res.value, &mut temp, &rhs.value); subtract(&mut res.value, &mut temp, &mut rhs.value.clone());
res res
} }
} }
@@ -64,13 +64,32 @@ macro_rules! subtraction_impls
type Output = $name; type Output = $name;
fn sub(self, rhs: &$name) -> $name { fn sub(self, rhs: &$name) -> $name {
let mut res = $name::zero(); let mut res = self.clone();
let mut temp = [0; $size]; let mut temp = [0; $size];
subtract(&mut res.value, &mut temp, &rhs.value); subtract(&mut res.value, &mut temp, &mut rhs.value.clone());
res res
} }
} }
} }
} }
//subtraction_impls!(U192, 3); #[cfg(test)]
macro_rules! generate_sub_tests {
($name: ident, $lname: ident) => {
#[test]
fn $lname() {
let fname = format!("testdata/sub/{}.tests", stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let c = $name::from_bytes(cbytes);
assert_eq!(c, a - b);
});
}
};
}

6006
testdata/add/U1024.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U1088.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U1216.tests vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6006
testdata/add/U192.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U2048.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U2112.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U256.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U3072.tests vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

6006
testdata/add/U3136.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U320.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U384.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U4096.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U4160.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U448.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U512.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U576.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U6208.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U640.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U7680.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U7744.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U8192.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U8256.tests vendored

File diff suppressed because it is too large Load Diff

6006
testdata/add/U832.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U1024.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U1088.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U1216.tests vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

7007
testdata/div/U192.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U2048.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U2112.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U256.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U3072.tests vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

7007
testdata/div/U3136.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U320.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U384.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U4096.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U4160.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U448.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U512.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U576.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U6208.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U640.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U7680.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U7744.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U8192.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U8256.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/div/U832.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U1024.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U1088.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U1216.tests vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

7007
testdata/mul/U192.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U2048.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U2112.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U256.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U3072.tests vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

7007
testdata/mul/U3136.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U320.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U384.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U4096.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U4160.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U448.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U512.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U576.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U6208.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U640.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U7680.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U7744.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U8192.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U8256.tests vendored

File diff suppressed because it is too large Load Diff

7007
testdata/mul/U832.tests vendored

File diff suppressed because it is too large Load Diff