Skip to content

Commit 6bb9e86

Browse files
committed
Rotate left/right impl (#9)
* Remove don'tpanic idea, not needed * Add rotate left/right
1 parent 890ea4b commit 6bb9e86

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fixed-bigint"
3-
version = "0.1.4"
3+
version = "0.1.5"
44
authors = ["kaidokert <[email protected]>"]
55
documentation = "https://docs.rs/fixed-bigint"
66
edition = "2018"

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ _TODO list_:
2121
* Implement experimental `unchecked_math` operands, unchecked_mul, unchecked_div etc.
2222
* Probably needs its own error structs instead of reusing core::fmt::Error and core::num::ParseIntError
2323
* Decimal string to/from conversion, currently only binary and hex strings are supported.
24-
* Implement a `dontpanic` feature, changing arithmetic ops to behave like wrapping versions, i.e. a non-standard C-like way.
2524
* Comprehensive testing fixture, fully validate all ops up to 32-bit against native types
2625
* Some test code relies on 64-bit ToPrimitive/FromPrimitive conversions, clean this up
2726
* Lots of test code can be written cleaner

src/fixeduint.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,6 @@ enum PanicReason {
10951095
RemByZero,
10961096
}
10971097

1098-
// todo: Add a "don't panic" option
10991098
fn maybe_panic(r: PanicReason) {
11001099
match r {
11011100
PanicReason::Add => panic!("attempt to add with overflow"),
@@ -1205,11 +1204,15 @@ impl<T: MachineWord, const N: usize> num_traits::PrimInt for FixedUInt<T, N> {
12051204
}
12061205
ret
12071206
}
1208-
fn rotate_left(self, _: u32) -> Self {
1209-
todo!()
1207+
fn rotate_left(self, bits: u32) -> Self {
1208+
let a = self << bits;
1209+
let b = self >> (Self::BIT_SIZE - bits as usize);
1210+
a | b
12101211
}
1211-
fn rotate_right(self, _: u32) -> Self {
1212-
todo!()
1212+
fn rotate_right(self, bits: u32) -> Self {
1213+
let a = self >> bits;
1214+
let b = self << (Self::BIT_SIZE - bits as usize);
1215+
a | b
12131216
}
12141217
fn signed_shl(self, _: u32) -> Self {
12151218
todo!()

tests/bit_shift.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,39 @@ fn test_sh_variants() {
225225
test_shifts::<u32, Bn<u16, 2>>(8, &left_ops, 0x20000000, &right_ops);
226226
test_shifts::<u32, Bn<u8, 4>>(8, &left_ops, 0x20000000, &right_ops);
227227
}
228+
229+
#[test]
230+
fn test_rotate() {
231+
fn test_rotate<
232+
T: num_traits::PrimInt,
233+
INT: num_traits::PrimInt + core::fmt::Debug + core::convert::From<T>,
234+
>(
235+
(a_ref, b_ref, c_ref): (T, T, T),
236+
half_shift: u32,
237+
full_shift: u32,
238+
) {
239+
let a: INT = a_ref.into();
240+
let b: INT = b_ref.into();
241+
let c: INT = c_ref.into();
242+
assert_eq!(a.rotate_left(1), b);
243+
assert_eq!(a.rotate_left(half_shift), c);
244+
assert_eq!(a.rotate_right(half_shift), c);
245+
assert_eq!(a.rotate_left(full_shift), a);
246+
assert_eq!(b.rotate_right(1), a);
247+
assert_eq!(b.rotate_right(full_shift), b);
248+
}
249+
let test_8bit = (0xc1, 0x83, 0x1C);
250+
test_rotate::<u8, u8>(test_8bit, 4, 8);
251+
test_rotate::<u8, Bn<u8, 1>>(test_8bit, 4, 8);
252+
253+
let test_16bit = (0xc001, 0x8003, 0x01C0);
254+
test_rotate::<u16, u16>(test_16bit, 8, 16);
255+
test_rotate::<u16, Bn<u8, 2>>(test_16bit, 8, 16);
256+
test_rotate::<u16, Bn<u16, 1>>(test_16bit, 8, 16);
257+
258+
let test_32bit = (0xc0000001u32, 0x80000003u32, 0x0001C000u32);
259+
test_rotate::<u32, u32>(test_32bit, 16, 32);
260+
test_rotate::<u32, Bn<u8, 4>>(test_32bit, 16, 32);
261+
test_rotate::<u32, Bn<u16, 2>>(test_32bit, 16, 32);
262+
test_rotate::<u32, Bn<u32, 1>>(test_32bit, 16, 32);
263+
}

0 commit comments

Comments
 (0)