From 8031391a61073e98d50e870511fef1175babe2f9 Mon Sep 17 00:00:00 2001 From: gbrochar Date: Sat, 28 May 2022 17:27:49 +0200 Subject: [PATCH] feat(ex00|ex01|ex02): adder, multiplier and gray code --- .gitignore | 5 +++++ Cargo.toml | 8 ++++++++ src/adder.rs | 15 +++++++++++++++ src/adder/tests.rs | 34 ++++++++++++++++++++++++++++++++++ src/gray_code.rs | 13 +++++++++++++ src/gray_code/tests.rs | 25 +++++++++++++++++++++++++ src/main.rs | 18 ++++++++++++++++++ src/multiplier.rs | 14 ++++++++++++++ src/multiplier/tests.rs | 34 ++++++++++++++++++++++++++++++++++ 9 files changed, 166 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/adder.rs create mode 100644 src/adder/tests.rs create mode 100644 src/gray_code.rs create mode 100644 src/gray_code/tests.rs create mode 100644 src/main.rs create mode 100644 src/multiplier.rs create mode 100644 src/multiplier/tests.rs diff --git a/.gitignore b/.gitignore index 62bd1a4..211d5d3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,8 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk + + +# Added by cargo + +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..287c1fd --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "ready_set_boole" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/adder.rs b/src/adder.rs new file mode 100644 index 0000000..2dfc4c6 --- /dev/null +++ b/src/adder.rs @@ -0,0 +1,15 @@ +mod tests; + +pub fn adder(a: u32, b: u32) -> u32 { + let mut result: u32 = 0; + let mut carriage: u32 = 0; + + for i in 0..32 { + let a_bit = a >> i & 1; + let b_bit = b >> i & 1; + result = result | (a_bit ^ b_bit ^ carriage) << i; + carriage = (a_bit & b_bit) | ((a_bit ^ b_bit) & carriage) + } + result +} + diff --git a/src/adder/tests.rs b/src/adder/tests.rs new file mode 100644 index 0000000..125f917 --- /dev/null +++ b/src/adder/tests.rs @@ -0,0 +1,34 @@ +#[cfg(test)] +mod tests { + use crate::adder::adder; + use std::num::Wrapping; + + #[test] + fn zero_plus_one() { + assert_eq!(adder(0, 1), 0 + 1); + } + + #[test] + fn four_plus_three() { + assert_eq!(adder(4, 3), 4 + 3); + } + + #[test] + fn one_plus_one() { + assert_eq!(adder(1, 1), 1 + 1); + } + + #[test] + fn random_numbers() { + assert_eq!(adder(632_235, 12_756), 632_235 + 12_756); + assert_eq!(adder(932_455, 654_756), 932_455 + 654_756); + assert_eq!(adder(332_875, 123_655), 332_875 + 123_655); + assert_eq!(adder(732_235_342, 234_756), 732_235_342 + 234_756); + } + + #[test] + fn overflow() { + let big = Wrapping(3_245_532_214u32); + assert_eq!(adder(3_245_532_214, 3_245_532_214), (big + big).0); + } +} diff --git a/src/gray_code.rs b/src/gray_code.rs new file mode 100644 index 0000000..108ea83 --- /dev/null +++ b/src/gray_code.rs @@ -0,0 +1,13 @@ +mod tests; + +pub fn gray_code(n: u32) -> u32 { + let mut result: u32 = n & 1 << 31; + + for i in (1..32).rev() { + let n_bit = n >> i & 1; + let n_right_bit = n << 1 >> i & 1; + result = result | (n_bit ^ n_right_bit) << i >> 1; + } + result +} + diff --git a/src/gray_code/tests.rs b/src/gray_code/tests.rs new file mode 100644 index 0000000..7903e01 --- /dev/null +++ b/src/gray_code/tests.rs @@ -0,0 +1,25 @@ +#[cfg(test)] +mod tests { + use crate::gray_code::gray_code; + + #[test] + fn digits() { + assert_eq!(gray_code(0), 0); + assert_eq!(gray_code(1), 1); + assert_eq!(gray_code(2), 3); + assert_eq!(gray_code(3), 2); + assert_eq!(gray_code(4), 6); + assert_eq!(gray_code(5), 7); + assert_eq!(gray_code(6), 5); + assert_eq!(gray_code(7), 4); + assert_eq!(gray_code(8), 12); + assert_eq!(gray_code(9), 13); + } + + #[test] + fn msb_u32() { + assert_eq!(gray_code(3_000_000_000), 3_954_733_312); + assert_eq!(gray_code(2_147_483_648), 3_221_225_472); + assert_eq!(gray_code(4_294_967_295), 2_147_483_648); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..bb1527a --- /dev/null +++ b/src/main.rs @@ -0,0 +1,18 @@ +mod adder; +mod multiplier; +mod gray_code; + +use gray_code::gray_code; + +fn main() { + println!("Hello, world!"); + println!("{}", gray_code(4_294_967_295)); + println!("{}", gray_code(511)); + println!("{}", gray_code(255)); + println!("{}", gray_code(127)); + println!("{}", gray_code(63)); + println!("{}", gray_code(31)); + println!("{}", gray_code(15)); + println!("{}", gray_code(7)); + println!("{}", gray_code(3)); +} diff --git a/src/multiplier.rs b/src/multiplier.rs new file mode 100644 index 0000000..2e208af --- /dev/null +++ b/src/multiplier.rs @@ -0,0 +1,14 @@ +mod tests; + +use crate::adder::adder; + +pub fn multiplier(a: u32, b: u32) -> u32 { + let mut result = 0; + + for i in 0..32 { + if a >> i & 1 == 1 { + result = adder(result, b << i); + } + } + result +} diff --git a/src/multiplier/tests.rs b/src/multiplier/tests.rs new file mode 100644 index 0000000..a650962 --- /dev/null +++ b/src/multiplier/tests.rs @@ -0,0 +1,34 @@ +#[cfg(test)] +mod tests { + use crate::multiplier::multiplier; + use std::num::Wrapping; + + #[test] + fn zero_times_one() { + assert_eq!(multiplier(0, 1), 0 * 1); + } + + #[test] + fn four_times_three() { + assert_eq!(multiplier(4, 3), 4 * 3); + } + + #[test] + fn one_times_one() { + assert_eq!(multiplier(1, 1), 1 * 1); + } + + #[test] + fn random_numbers() { + assert_eq!(multiplier(62_235, 12_756), 62_235 * 12_756); + assert_eq!(multiplier(93_455, 4_756), 93_455 * 4_756); + assert_eq!(multiplier(32_875, 23_655), 32_875 * 23_655); + assert_eq!(multiplier(732_342, 796), 732_342 * 796); + } + + #[test] + fn overflow() { + let big = Wrapping(3_245_532_214u32); + assert_eq!(multiplier(3_245_532_214, 3_245_532_214), (big * big).0); + } +}