From 81f190dc607e6f10d950b4198d2e1d02b446b40a Mon Sep 17 00:00:00 2001 From: Rhinemann Date: Tue, 27 Jun 2023 21:05:56 +0300 Subject: [PATCH] Catching up with master branch. --- src/bit_utilities.rs | 146 +++++++++++++++++++++++++++++++++++-------- src/main.rs | 70 ++++++++++----------- 2 files changed, 153 insertions(+), 63 deletions(-) diff --git a/src/bit_utilities.rs b/src/bit_utilities.rs index aee3881..8784335 100644 --- a/src/bit_utilities.rs +++ b/src/bit_utilities.rs @@ -1,5 +1,6 @@ -use std::fmt; +use std::collections::VecDeque; use std::fmt::Formatter; +use std::{cmp, fmt}; fn capitalise(s: &str) -> String { let mut c = s.chars(); @@ -13,42 +14,79 @@ fn capitalise(s: &str) -> String { #[derive(Debug)] pub struct BasicRegister { /// A [Vec] that stores the binary data of the register. - memory: Vec, + memory: VecDeque, } impl BasicRegister { - pub fn l_shift(&mut self) { - let mut res: Vec = vec![false; self.memory.len()]; + pub fn adjusted_by_size(&mut self, resulting_size: usize) -> Self { + let current_memory_size: usize = self.memory.len(); + let difference: i32 = current_memory_size as i32 - resulting_size as i32; - res[..(self.memory.len() - 1)] - .copy_from_slice(&self.memory[1..((self.memory.len() - 1) + 1)]); - - self.memory = res; - } - - pub fn r_shift(&mut self) { - let mut res: Vec = vec![false; self.memory.len()]; - - for i in (1..self.memory.len()).rev() { - res[i] = self.memory[i - 1]; + match current_memory_size > resulting_size { + true => BasicRegister::new( + (difference as usize..current_memory_size) + .map(|i| self.memory[i]) + .collect::>(), + ), + false => { + let mut resulting_memory: VecDeque = vec![false; -difference as usize].into(); + resulting_memory.append(&mut self.memory); + BasicRegister::new(resulting_memory) + } } - - self.memory = res; } - pub fn reverse(&mut self) { + pub fn negate(&mut self) { self.memory = self.memory.iter().map(|val| !val).collect(); } - pub fn new(memory: Vec) -> Self { + pub fn negated(&self) -> Self { + BasicRegister::new(self.memory.iter().map(|val| !val).collect()) + } + + pub fn left_shift( + &mut self, + shift_in_value_default: Option, + bits_shifted_default: Option, + ) -> VecDeque { + let shift_in_value: bool = shift_in_value_default.unwrap_or(false); + let bits_shifted: usize = bits_shifted_default.unwrap_or(1) as usize; + + let mut shifted_bits: VecDeque = [].into(); + (0..bits_shifted).for_each(|_| shifted_bits.push_back(self.memory.pop_front().unwrap())); + (0..bits_shifted).for_each(|_| self.memory.push_back(shift_in_value)); + + shifted_bits + } + + pub fn right_shift( + &mut self, + shift_in_value_default: Option, + bits_shifted_default: Option, + ) -> VecDeque { + let shift_in_value: bool = shift_in_value_default.unwrap_or(false); + let bits_shifted: usize = bits_shifted_default.unwrap_or(1) as usize; + + let mut shifted_bits: VecDeque = [].into(); + (0..bits_shifted).for_each(|_| shifted_bits.push_back(self.memory.pop_back().unwrap())); + (0..bits_shifted).for_each(|_| self.memory.push_front(shift_in_value)); + + shifted_bits + } + + pub fn new(memory: VecDeque) -> Self { Self { memory } } + + pub fn len(&self) -> usize { + self.memory.len() + } } impl Default for BasicRegister { fn default() -> Self { Self { - memory: vec![false], + memory: [false].into(), } } } @@ -80,6 +118,10 @@ impl fmt::Binary for BasicRegister { } } +fn u8_to_bool(number: u8) -> bool { + number > 0 +} + fn read_vec(variable_name: &str) -> Vec { loop { print!("Enter {variable_name}: "); @@ -94,13 +136,13 @@ fn read_vec(variable_name: &str) -> Vec { } } -pub fn char_to_bool_vector(char_vector: Vec) -> Vec { - let mut bool_vector: Vec = Vec::new(); +pub fn char_to_bool_vector(char_vector: Vec) -> VecDeque { + let mut bool_vector: VecDeque = VecDeque::new(); for value in char_vector.iter() { match value { - '0' => bool_vector.push(false), - '1' => bool_vector.push(true), + '0' => bool_vector.push_back(false), + '1' => bool_vector.push_back(true), _ => (), } } @@ -108,6 +150,60 @@ pub fn char_to_bool_vector(char_vector: Vec) -> Vec { bool_vector } -pub fn get_memory(variable_name: &str) -> Vec { +pub fn get_memory(variable_name: &str) -> VecDeque { char_to_bool_vector(read_vec(variable_name)) } + +pub fn align_registers( + mut first_register: BasicRegister, + mut second_register: BasicRegister, +) -> (BasicRegister, BasicRegister) { + let first_size: usize = first_register.memory.len(); + let second_size: usize = second_register.memory.len(); + let required_size: usize = cmp::max(first_size, second_size); + + ( + first_register.adjusted_by_size(required_size), + second_register.adjusted_by_size(required_size), + ) +} + +fn binary_sum_with_carry( + first_term: &BasicRegister, + second_term: &BasicRegister, +) -> (BasicRegister, bool) { + let mut sum: BasicRegister = BasicRegister::new(vec![false; first_term.len()].into()); + + let mut carry: bool = false; + let mut current_bit_sum: u8; + for i in (1..first_term.len()).rev() { + current_bit_sum = first_term.memory[i] as u8 + second_term.memory[i] as u8 + carry as u8; + carry = u8_to_bool(current_bit_sum & 2); + sum.memory[i] = u8_to_bool(current_bit_sum & 1); + } + + let final_bit_sum: u8 = first_term.memory[0] as u8 + second_term.memory[0] as u8 + carry as u8; + let final_carry: bool = u8_to_bool(final_bit_sum & 2); + + sum.memory[0] = u8_to_bool(final_bit_sum & 1); + + (sum, final_carry) +} + +pub fn binary_sum(first_term: &BasicRegister, second_term: &BasicRegister) -> BasicRegister { + binary_sum_with_carry(first_term, second_term).0 +} + +pub fn binary_subtraction(minuend: &BasicRegister, subtrahend: &BasicRegister) -> BasicRegister { + let (difference, final_carry) = binary_sum_with_carry(minuend, &subtrahend.negated()); + + match final_carry { + true => { + let mut complement = vec![false; difference.len() - 1]; + complement.append(&mut vec![true]); + binary_sum(&difference, &BasicRegister::new(complement.into())) + } + false => difference.negated(), + } + // BasicRegister::default() +} diff --git a/src/main.rs b/src/main.rs index 9dedd90..963cd62 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,45 +1,39 @@ #[allow(dead_code)] mod bit_utilities; -use bit_utilities::*; -// use text_io::read; +use bit_utilities as bu; +use text_io::read; + +fn input_handler(first_register: bu::BasicRegister, second_register: bu::BasicRegister) { + let (first_register, second_register) = bu::align_registers(first_register, second_register); + + println!(); + println!("{}", first_register); + println!("{}", second_register); + + loop { + print!("\nChoose the operation:\n[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit\n>>> "); + let input: String = read!(); + match input.as_str() { + "a" => println!( + "Sum:\n{}", + bu::binary_sum(&first_register, &second_register) + ), + "s" => println!( + "Subtraction:\n{}", + bu::binary_subtraction(&first_register, &second_register) + ), + "m" => (), + "d" => (), + "q" => std::process::exit(0x0100), + _ => println!("Not an available operation, try again."), + } + } +} fn main() { - let mut reg = BasicRegister::new(get_memory("your number")); - // let mut reg: BasicRegister = Default::default(); + let reg = bu::BasicRegister::new(bu::get_memory("your number")); + let reg2 = bu::BasicRegister::new(bu::get_memory("your number")); - println!("\nRegister:"); - println!("{}", reg); - println!("{:b}", reg); - - // println!("\nShifted right:"); - // reg.r_shift(); - // println!("{}", reg); - // - // println!("\nShifted left:"); - // reg.l_shift(); - // println!("{}", reg); - // - // println!("\nReversed:"); - // reg.reverse(); - // println!("{}", reg); - - // println!("{}", true); - // println!("{}", true); - - // let a: i8 = read!(); - // println!("{} {0:b}", a); - // println!("{} {0:b}", a >> 1); - // println!("{} {0:b}", a << 1); - // println!("{} {0:b}", !a); - // println!("{}", '3'.to_digit(2).unwrap()); - // let f_text = format!("{a:b}").chars().collect::>(); - // println!("{:?}", f_text); - // println!("{:?}", char_to_bool_vector(f_text.clone())); - // let b: BasicRegister = BasicRegister::new(char_to_bool_vector(f_text)); - // b.print_register(); - // println!("{:?}", get_memory(format!("{a:b}"))); - // println!("{:?}", a.split(" ").collect::>()); - // a = text_io::read!("{}\n"); - // println!("{a}") + input_handler(reg, reg2); }