Skip to content

Commit

Permalink
Rotate left/right impl (#9)
Browse files Browse the repository at this point in the history
* Remove don'tpanic idea, not needed

* Add rotate left/right
  • Loading branch information
kaidokert committed Apr 17, 2021
1 parent 890ea4b commit 6bb9e86
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fixed-bigint"
version = "0.1.4"
version = "0.1.5"
authors = ["kaidokert <kaidokert@gmail.com>"]
documentation = "https://docs.rs/fixed-bigint"
edition = "2018"
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ _TODO list_:
* Implement experimental `unchecked_math` operands, unchecked_mul, unchecked_div etc.
* Probably needs its own error structs instead of reusing core::fmt::Error and core::num::ParseIntError
* Decimal string to/from conversion, currently only binary and hex strings are supported.
* Implement a `dontpanic` feature, changing arithmetic ops to behave like wrapping versions, i.e. a non-standard C-like way.
* Comprehensive testing fixture, fully validate all ops up to 32-bit against native types
* Some test code relies on 64-bit ToPrimitive/FromPrimitive conversions, clean this up
* Lots of test code can be written cleaner
Expand Down
13 changes: 8 additions & 5 deletions src/fixeduint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,6 @@ enum PanicReason {
RemByZero,
}

// todo: Add a "don't panic" option
fn maybe_panic(r: PanicReason) {
match r {
PanicReason::Add => panic!("attempt to add with overflow"),
Expand Down Expand Up @@ -1205,11 +1204,15 @@ impl<T: MachineWord, const N: usize> num_traits::PrimInt for FixedUInt<T, N> {
}
ret
}
fn rotate_left(self, _: u32) -> Self {
todo!()
fn rotate_left(self, bits: u32) -> Self {
let a = self << bits;
let b = self >> (Self::BIT_SIZE - bits as usize);
a | b
}
fn rotate_right(self, _: u32) -> Self {
todo!()
fn rotate_right(self, bits: u32) -> Self {
let a = self >> bits;
let b = self << (Self::BIT_SIZE - bits as usize);
a | b
}
fn signed_shl(self, _: u32) -> Self {
todo!()
Expand Down
36 changes: 36 additions & 0 deletions tests/bit_shift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,39 @@ fn test_sh_variants() {
test_shifts::<u32, Bn<u16, 2>>(8, &left_ops, 0x20000000, &right_ops);
test_shifts::<u32, Bn<u8, 4>>(8, &left_ops, 0x20000000, &right_ops);
}

#[test]
fn test_rotate() {
fn test_rotate<
T: num_traits::PrimInt,
INT: num_traits::PrimInt + core::fmt::Debug + core::convert::From<T>,
>(
(a_ref, b_ref, c_ref): (T, T, T),
half_shift: u32,
full_shift: u32,
) {
let a: INT = a_ref.into();
let b: INT = b_ref.into();
let c: INT = c_ref.into();
assert_eq!(a.rotate_left(1), b);
assert_eq!(a.rotate_left(half_shift), c);
assert_eq!(a.rotate_right(half_shift), c);
assert_eq!(a.rotate_left(full_shift), a);
assert_eq!(b.rotate_right(1), a);
assert_eq!(b.rotate_right(full_shift), b);
}
let test_8bit = (0xc1, 0x83, 0x1C);
test_rotate::<u8, u8>(test_8bit, 4, 8);
test_rotate::<u8, Bn<u8, 1>>(test_8bit, 4, 8);

let test_16bit = (0xc001, 0x8003, 0x01C0);
test_rotate::<u16, u16>(test_16bit, 8, 16);
test_rotate::<u16, Bn<u8, 2>>(test_16bit, 8, 16);
test_rotate::<u16, Bn<u16, 1>>(test_16bit, 8, 16);

let test_32bit = (0xc0000001u32, 0x80000003u32, 0x0001C000u32);
test_rotate::<u32, u32>(test_32bit, 16, 32);
test_rotate::<u32, Bn<u8, 4>>(test_32bit, 16, 32);
test_rotate::<u32, Bn<u16, 2>>(test_32bit, 16, 32);
test_rotate::<u32, Bn<u32, 1>>(test_32bit, 16, 32);
}

0 comments on commit 6bb9e86

Please sign in to comment.