Skip to content

Commit

Permalink
arithmetic: test shifts
Browse files Browse the repository at this point in the history
  • Loading branch information
ekiwi committed May 23, 2024
1 parent 76fd9b1 commit 15b3849
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 112 deletions.
3 changes: 3 additions & 0 deletions proptest-regressions/arithmetic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 5290d03e20dc8ead48a564a4df1f5a7ac522f13976a595ff42342a6a5a920e18 # shrinks to (s, msb, lsb) = ("", 0, 0)
cc cbfc3e8761ac7923718ed350fdf90de1098dbb8a80ac794ba3f9bd7cbbbc4938 # shrinks to (s, by) = ("1", 716052416)
cc 1740557fa41275b12cc7360e57ee7f4559e19340417ea715b0b2e091752c435b # shrinks to (s, by) = ("1", 1292759630)
cc 8c11598f6722b491fe336e0ea5f244658013097af2c7c877239e4caeed20f6f8 # shrinks to (s, by) = ("0", 2)
181 changes: 69 additions & 112 deletions src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,65 @@ mod tests {
.prop_flat_map(|(bits, msb)| (Just(bits), Just(msb), 0..(msb + 1)))
}

fn width_int_to_bit_str(value: WidthInt, width: WidthInt) -> String {
let mut words = value_vec(width);
// make sure the shift amount fits into the width
assert_eq!(
(value as Word) & mask(width),
value as Word,
"shift amount is too large: {value} > {}",
mask(width)
);
words[0] = value as Word;
to_bit_str(&words, width)
}

fn do_test_shift(src: &str, by: WidthInt, right: bool) {
let (a_vec, a_width) = from_bit_str(src);
let b = width_int_to_bit_str(by, a_width);
let (b_vec, b_width) = from_bit_str(&b);
assert_eq!(a_width, b_width);
let mut res_vec = vec![0 as Word; a_vec.len()];
if right {
shift_right(&mut res_vec, &a_vec, &b_vec, a_width);
} else {
shift_left(&mut res_vec, &a_vec, &b_vec, a_width);
}
assert_unused_bits_zero(&res_vec, a_width);
let zeros = std::cmp::min(by, a_width) as usize;
let mut expected: String = "0".repeat(zeros);
if right {
let msb: String = src.chars().take(a_width as usize - zeros).collect();
expected.push_str(&msb);
} else {
let mut msb: String = src.chars().skip(zeros).collect();
msb.push_str(&expected);
expected = msb;
}
assert_eq!(to_bit_str(&res_vec, a_width), expected);
}

fn do_test_shift_right(src: &str, by: WidthInt) {
do_test_shift(src, by, true)
}
fn do_test_shift_left(src: &str, by: WidthInt) {
do_test_shift(src, by, false)
}

/// biases `by` value to be more interesting
fn shift_args() -> impl Strategy<Value = (String, WidthInt)> {
"[01]+".prop_flat_map(|bits: String| {
let len = std::cmp::max(bits.len(), 1);
let max_shift =
std::cmp::min(mask(bits.len() as WidthInt) + 1, WidthInt::MAX as Word) as WidthInt;
let by = prop_oneof![0..(len as WidthInt), 0..(max_shift)];
(Just(bits), by)
})
}

#[test]
fn test_shift_right_regression() {}

proptest! {
#![proptest_config(ProptestConfig::with_cases(10000))]
#[test]
Expand All @@ -468,6 +527,16 @@ mod tests {
fn test_slice((s, msb, lsb) in slice_args()) {
do_test_slice(&s, msb, lsb);
}

#[test]
fn test_shift_right((s, by) in shift_args()) {
do_test_shift_right(&s, by);
}

#[test]
fn test_shift_left((s, by) in shift_args()) {
do_test_shift_left(&s, by);
}
}
}

Expand Down Expand Up @@ -497,118 +566,6 @@ mod tests {
// }
//
//
// fn do_test_slice(src: &str, hi: WidthInt, lo: WidthInt) {
// let (src_vec, src_width) = from_bit_str(src);
// assert!(hi >= lo);
// assert!(hi < src_width);
// let res_width = hi - lo + 1;
// let mut res_vec = vec![0 as Word; res_width.div_ceil(Word::BITS) as usize];
// slice(&mut res_vec, &src_vec, hi, lo);
// assert_unused_bits_zero(&res_vec, res_width);
// let expected: String = src
// .chars()
// .skip((src_width - 1 - hi) as usize)
// .take(res_width as usize)
// .collect();
// assert_eq!(to_bit_str(&res_vec, res_width), expected);
// }
//
// #[test]
// fn test_slice() {
// let mut rng = rand_xoshiro::Xoshiro256PlusPlus::seed_from_u64(1);
// let in0 = random_bit_str(15, &mut rng);
// // do_test_slice(&in0, 0, 0);
// do_test_slice(&in0, 1, 1);
// do_test_slice(&in0, 6, 0);
// do_test_slice(&in0, 6, 4);
//
// // test slice across two words
// let in1 = random_bit_str((2 * Word::BITS) - 5, &mut rng);
// do_test_slice(&in1, Word::BITS, Word::BITS - 5);
// do_test_slice(&in1, Word::BITS + 5, Word::BITS - 5);
//
// // test larger slices
// let in2 = random_bit_str(1354, &mut rng);
// do_test_slice(&in2, 400, 400); // 400 = 6 * 64 + 16
// do_test_slice(&in2, 400, 400 - 20);
// do_test_slice(&in2, 400 + 13, 400 - 20);
//
// // result is larger than one word
// do_test_slice(&in2, 875, Word::BITS * 13); // aligned to word boundaries
// do_test_slice(&in2, 3 + (Word::BITS * 2) + 11, 3);
// do_test_slice(&in2, 875, 875 - (Word::BITS * 2) - 15);
// }
//
// fn width_int_to_bit_str(value: WidthInt, width: WidthInt) -> String {
// let mut words = vec![0 as Word; width.div_ceil(Word::BITS) as usize];
// words[0] = value as Word;
// to_bit_str(&words, width)
// }
//
// fn do_test_shift(src: &str, by: WidthInt, right: bool) {
// let (a_vec, a_width) = from_bit_str(src);
// let (b_vec, b_width) = from_bit_str(&width_int_to_bit_str(by, a_width));
// assert_eq!(a_width, b_width);
// let mut res_vec = vec![0 as Word; a_vec.len()];
// if right {
// shift_right(&mut res_vec, &a_vec, &b_vec, a_width);
// } else {
// shift_left(&mut res_vec, &a_vec, &b_vec, a_width);
// }
// assert_unused_bits_zero(&res_vec, a_width);
// let zeros = std::cmp::min(by, a_width) as usize;
// let mut expected: String = "0".repeat(zeros);
// if right {
// let msb: String = src.chars().take(a_width as usize - zeros).collect();
// expected.push_str(&msb);
// } else {
// let mut msb: String = src.chars().skip(zeros).collect();
// msb.push_str(&expected);
// expected = msb;
// }
// assert_eq!(to_bit_str(&res_vec, a_width), expected);
// }
//
// fn do_test_shift_right(src: &str, by: WidthInt) {
// do_test_shift(src, by, true)
// }
// fn do_test_shift_left(src: &str, by: WidthInt) {
// do_test_shift(src, by, false)
// }
//
// #[test]
// fn test_shift_right() {
// let mut rng = rand_xoshiro::Xoshiro256PlusPlus::seed_from_u64(1);
// let in0 = random_bit_str(15, &mut rng);
// do_test_shift_right(&in0, 0);
// do_test_shift_right(&in0, 3);
// do_test_shift_right(&in0, 14);
// do_test_shift_right(&in0, 30);
//
// let in1 = random_bit_str(157, &mut rng);
// do_test_shift_right(&in1, 0);
// do_test_shift_right(&in1, 3);
// do_test_shift_right(&in1, 14);
// do_test_shift_right(&in1, 150);
// do_test_shift_right(&in1, 200);
// }
//
// #[test]
// fn test_shift_left() {
// let mut rng = rand_xoshiro::Xoshiro256PlusPlus::seed_from_u64(1);
// let in0 = random_bit_str(15, &mut rng);
// do_test_shift_left(&in0, 0);
// do_test_shift_left(&in0, 3);
// do_test_shift_left(&in0, 14);
// do_test_shift_left(&in0, 30);
//
// let in1 = random_bit_str(157, &mut rng);
// do_test_shift_left(&in1, 0);
// do_test_shift_left(&in1, 3);
// do_test_shift_left(&in1, 14);
// do_test_shift_left(&in1, 150);
// do_test_shift_left(&in1, 200);
// }
//
// fn do_test_zero_ext(src: &str, by: WidthInt) {
// let (src_vec, src_width) = from_bit_str(src);
Expand Down

0 comments on commit 15b3849

Please sign in to comment.