Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement left_rotate, right_rotate #38

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 82 additions & 2 deletions src/bitline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ pub trait Bitline {
/// assert_eq!((0b00111000 as Bitline8).first_index(), Some(2));
/// assert_eq!((0b00000000 as Bitline8).first_index(), None);
/// ```

fn first_index(&self) -> Option<usize>;

/// Return the last bit index that is set to one.
/// If there is no bit set to one, return None.
/// # Examples
Expand Down Expand Up @@ -283,6 +283,29 @@ pub trait Bitline {
/// assert_eq!(0b01101100_u8.bit_repr(), "01101100");
/// ```
fn bit_repr(&self) -> String;

/// Return the bits rotated to the left by n bits.
/// Overflowed bits are moved to the right side.
/// # Examples
/// ```
/// use bittersweet::bitline::{Bitline, Bitline8};
/// let bitline = 0b01101100_u8;
/// assert_eq!(bitline.left_rotate(1), 0b11011000_u8);
/// assert_eq!(bitline.left_rotate(2), 0b10110001_u8);
/// ```
fn left_rotate(&self, n: usize) -> Self;

/// Return the bits rotated to the right by n bits.
/// Overflowed bits are moved to the left side.
/// # Examples
/// ```
/// use bittersweet::bitline::{Bitline, Bitline8};
/// let bitline = 0b01101100_u8;
/// assert_eq!(bitline.right_rotate(1), 0b00110110_u8);
/// assert_eq!(bitline.right_rotate(2), 0b00011011_u8);
/// assert_eq!(bitline.right_rotate(3), 0b10001101_u8);
/// ```
fn right_rotate(&self, n: usize) -> Self;
}

macro_rules! impl_Bitline {
Expand Down Expand Up @@ -393,7 +416,6 @@ macro_rules! impl_Bitline {
let last_index = self.last_index().unwrap();
Self::by_range(first_index, last_index + 1)
}

#[inline]
fn length() -> usize {
Self::BITS as usize
Expand Down Expand Up @@ -428,6 +450,22 @@ macro_rules! impl_Bitline {
let lack_bits = Self::length() - formatted.len();
"0".repeat(lack_bits) + &formatted
}
#[inline]
fn left_rotate(&self, n: usize) -> Self {
let n = n % Self::length();
if (n == 0) {
return *self;
}
(self << n) | (self >> (Self::length() - n))
}
#[inline]
fn right_rotate(&self, n: usize) -> Self {
let n = n % Self::length();
if (n == 0) {
return *self;
}
(self >> n) | (self << (Self::length() - n))
}
}
};
}
Expand Down Expand Up @@ -653,3 +691,45 @@ fn test_remove() {
fn test_bin_repr() {
assert_eq!(0b11110000_u8.bit_repr(), "11110000");
}

#[test]
fn test_left_rotate() {
// 0 means no change
assert_eq!(0b11110000_u8.left_rotate(0), 0b11110000_u8);

assert_eq!(0b11110000_u8.left_rotate(1), 0b11100001_u8);
assert_eq!(0b11110000_u8.left_rotate(2), 0b11000011_u8);
assert_eq!(0b11110000_u8.left_rotate(3), 0b10000111_u8);
assert_eq!(0b11110000_u8.left_rotate(4), 0b00001111_u8);
assert_eq!(0b11110000_u8.left_rotate(5), 0b00011110_u8);
assert_eq!(0b11110000_u8.left_rotate(6), 0b00111100_u8);
assert_eq!(0b11110000_u8.left_rotate(7), 0b01111000_u8);
assert_eq!(0b11110000_u8.left_rotate(8), 0b11110000_u8);
assert_eq!(0b11110000_u8.left_rotate(9), 0b11100001_u8);
}

#[test]
fn test_right_rotate() {
// 0 means no change
assert_eq!(0b11110000_u8.right_rotate(0), 0b11110000_u8);

assert_eq!(0b11110000_u8.right_rotate(1), 0b01111000_u8);
assert_eq!(0b11110000_u8.right_rotate(2), 0b00111100_u8);
assert_eq!(0b11110000_u8.right_rotate(3), 0b00011110_u8);
assert_eq!(0b11110000_u8.right_rotate(4), 0b00001111_u8);
assert_eq!(0b11110000_u8.right_rotate(5), 0b10000111_u8);
assert_eq!(0b11110000_u8.right_rotate(6), 0b11000011_u8);
assert_eq!(0b11110000_u8.right_rotate(7), 0b11100001_u8);
assert_eq!(0b11110000_u8.right_rotate(8), 0b11110000_u8);
assert_eq!(0b11110000_u8.right_rotate(9), 0b01111000_u8);
}

#[test]
fn test_right_rotate_and_left_rotate_is_reversible() {
for bitline in 0..256 {
for i in 0..128 {
let bitline = bitline as u8;
assert_eq!(bitline.right_rotate(i).left_rotate(i), bitline);
}
}
}