From 8f345f73d9606211b197b24fb615004695effe15 Mon Sep 17 00:00:00 2001 From: muytingc Date: Wed, 9 Dec 2020 17:04:03 -0500 Subject: [PATCH 1/3] added bitwise operators file and implemented bitwise and operations. Have no implemented converting BigInt to two's complement binary numbers currently, but will be necessary in future versions --- include/BigInt.hpp | 3 + include/operators/bitwise.hpp | 107 ++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 include/operators/bitwise.hpp diff --git a/include/BigInt.hpp b/include/BigInt.hpp index e3be86c..01c88cc 100644 --- a/include/BigInt.hpp +++ b/include/BigInt.hpp @@ -90,6 +90,9 @@ class BigInt { bool operator==(const std::string&) const; bool operator!=(const std::string&) const; + //Bitwise operators: + BigInt operator&(const BigInt& num) const; + // I/O stream operators: friend std::istream& operator>>(std::istream&, BigInt&); friend std::ostream& operator<<(std::ostream&, const BigInt&); diff --git a/include/operators/bitwise.hpp b/include/operators/bitwise.hpp new file mode 100644 index 0000000..88aeee9 --- /dev/null +++ b/include/operators/bitwise.hpp @@ -0,0 +1,107 @@ +/* + =========================================================================== + Bitwise operators + =========================================================================== +*/ + +#ifndef BIG_INT_BITWISE_OPERATORS_HPP +#define BIG_INT_BITWISE_OPERATORS_HPP + +#include +#include +#include +#include + +#include "BigInt.hpp" +#include "functions/utility.hpp" + +/* + to_binary + --------- + Converts a BigInt to a binary string. +*/ + +std::string to_binary(const BigInt& num){ + BigInt copy_num(num); + std::string binary_num; + + //Does not currently support two's complement binary strings + while(copy_num > 0){ + if(copy_num % 2 == 1){ + binary_num += "1"; + } + else{ + binary_num += "0"; + } + copy_num /= 2; + } + + return binary_num; +} + +/* + binary_to_decimal + --------- + Converts a binary string to a decimal string. +*/ + +BigInt binary_to_decimal(const std::string num){ + BigInt decimal_string; + + //Does not currently support two's complement binary strings + for(int i = num.size() - 1; i >= 0; i--){ + if(num[i] == '1'){ + decimal_string += pow(2, (num.size() - 1) - i); + } + } + + return decimal_string; +} + + +/* + BigInt & BigInt + --------------- + The operand on the RHS of the addition is `num`. +*/ + +BigInt BigInt::operator&(const BigInt& num) const{ + std::string lhs_binary, rhs_binary; + lhs_binary = to_binary(*this); + rhs_binary = to_binary(num); + + std::string larger, smaller; + std::tie(larger, smaller) = get_larger_and_smaller(lhs_binary, rhs_binary); + + std::string complete_string; + for(int i = 0; i < larger.size(); i++){ + if(larger[i] == '1' && smaller[i] == '1'){ + complete_string += "1"; + } + else{ + complete_string += "0"; + } + } + + return binary_to_decimal(complete_string); +} + +/* + BigInt | BigInt + --------------- + The operand on the RHS of the addition is `num`. +*/ + +/* + BigInt ^ BigInt + --------------- + The operand on the RHS of the addition is `num`. +*/ + +/* + ~ BigInt + --------------- + The operand on the RHS of the addition is `num`. +*/ + +#endif // BIG_INT_BITWISE_OPERATORS_HPP \ No newline at end of file From c6fbb306e77c79648382f378439a713ff2e394dc Mon Sep 17 00:00:00 2001 From: muytingc Date: Wed, 9 Dec 2020 21:44:07 -0500 Subject: [PATCH 2/3] Added support for bitwise or, xor, and not operators --- include/BigInt.hpp | 3 ++ include/operators/bitwise.hpp | 63 +++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/include/BigInt.hpp b/include/BigInt.hpp index 01c88cc..9c476d1 100644 --- a/include/BigInt.hpp +++ b/include/BigInt.hpp @@ -92,6 +92,9 @@ class BigInt { //Bitwise operators: BigInt operator&(const BigInt& num) const; + BigInt operator|(const BigInt& num) const; + BigInt operator^(const BigInt& num) const; + BigInt operator~() const; // I/O stream operators: friend std::istream& operator>>(std::istream&, BigInt&); diff --git a/include/operators/bitwise.hpp b/include/operators/bitwise.hpp index 88aeee9..3501e6a 100644 --- a/include/operators/bitwise.hpp +++ b/include/operators/bitwise.hpp @@ -45,7 +45,7 @@ std::string to_binary(const BigInt& num){ Converts a binary string to a decimal string. */ -BigInt binary_to_decimal(const std::string num){ +BigInt binary_to_BigInt(const std::string num){ BigInt decimal_string; //Does not currently support two's complement binary strings @@ -83,7 +83,7 @@ BigInt BigInt::operator&(const BigInt& num) const{ } } - return binary_to_decimal(complete_string); + return binary_to_BigInt(complete_string); } /* @@ -92,16 +92,75 @@ BigInt BigInt::operator&(const BigInt& num) const{ The operand on the RHS of the addition is `num`. */ +BigInt BigInt::operator|(const BigInt& num) const{ + std::string lhs_binary, rhs_binary; + lhs_binary = to_binary(*this); + rhs_binary = to_binary(num); + + std::string larger, smaller; + std::tie(larger, smaller) = get_larger_and_smaller(lhs_binary, rhs_binary); + + std::string complete_string; + for(int i = 0; i < larger.size(); i++){ + if(larger[i] == '1' || smaller[i] == '1'){ + complete_string += "1"; + } + else{ + complete_string += "0"; + } + } + + return binary_to_BigInt(complete_string); +} + /* BigInt ^ BigInt --------------- The operand on the RHS of the addition is `num`. */ +BigInt BigInt::operator^(const BigInt& num) const{ + std::string lhs_binary, rhs_binary; + lhs_binary = to_binary(*this); + rhs_binary = to_binary(num); + + std::string larger, smaller; + std::tie(larger, smaller) = get_larger_and_smaller(lhs_binary, rhs_binary); + + std::string complete_string; + for(int i = 0; i < larger.size(); i++){ + if((larger[i] == '1' && smaller[i] == '0') || (larger[i] == '0' && smaller[i] == '1')){ + complete_string += "1"; + } + else{ + complete_string += "0"; + } + } + + return binary_to_BigInt(complete_string); +} + /* ~ BigInt --------------- The operand on the RHS of the addition is `num`. */ +BigInt BigInt::operator~() const{ + std::string lhs_binary; + lhs_binary = to_binary(*this); + + std::string complete_string; + for(int i = 0; i < lhs_binary.size(); i++){ + if(lhs_binary[i] == '1'){ + complete_string += "0"; + } + else{ + complete_string += "1"; + } + } + + return binary_to_BigInt(complete_string); +} + #endif // BIG_INT_BITWISE_OPERATORS_HPP \ No newline at end of file From 7a3ef0248c251176b836a3273acb43cff78d2648 Mon Sep 17 00:00:00 2001 From: muytingc Date: Fri, 11 Dec 2020 14:45:44 -0500 Subject: [PATCH 3/3] added support for BigInt to two's complement binary numbers, sign extension of two's complement binary numbers, and two's complement binary numbers back to BigInt type --- include/operators/bitwise.hpp | 87 +++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/include/operators/bitwise.hpp b/include/operators/bitwise.hpp index 3501e6a..5cd891e 100644 --- a/include/operators/bitwise.hpp +++ b/include/operators/bitwise.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "BigInt.hpp" #include "functions/utility.hpp" @@ -25,39 +26,105 @@ std::string to_binary(const BigInt& num){ BigInt copy_num(num); std::string binary_num; - //Does not currently support two's complement binary strings + if(copy_num < 0){ + copy_num *= -1; + } + while(copy_num > 0){ if(copy_num % 2 == 1){ - binary_num += "1"; + binary_num = "1" + binary_num; } else{ - binary_num += "0"; + binary_num = "0" + binary_num; } copy_num /= 2; } + if(num < 0){ + for(int i = binary_num.size() - 1; i >= 0; i--){ + if(binary_num[i] == '0'){ + binary_num[i] = '1'; + } + else{ + binary_num[i] = '0'; + } + } + + bool carry_bit = true; + for(int i = binary_num.size() - 1; i >= 0; i--){ + if(binary_num[i] == '1' && carry_bit){ + binary_num[i] = '0'; + carry_bit = true; + } + else if(binary_num[i] == '0' && carry_bit){ + binary_num[i] = '1'; + carry_bit = false; + } + } + + binary_num = "1" + binary_num; + } + else if(num > 0){ + binary_num = "0" + binary_num; + } + else{ + binary_num = "0"; + } + return binary_num; } /* - binary_to_decimal + binary_to_BigInt --------- - Converts a binary string to a decimal string. + Converts a binary string to a BigInt. */ BigInt binary_to_BigInt(const std::string num){ BigInt decimal_string; - //Does not currently support two's complement binary strings - for(int i = num.size() - 1; i >= 0; i--){ + for(int i = num.size() - 1; i > 0; i--){ if(num[i] == '1'){ decimal_string += pow(2, (num.size() - 1) - i); } } + if(num[0] == '1'){ + decimal_string += (pow(2, (num.size() - 1)) * -1); + } + return decimal_string; } +/* + sign_extend_binary + --------- + Extends a binary string to match the length of the longest binary string passed in while maintaining 2's Complement. +*/ + +std::tuple sign_extend_binary(const std::string& num1, const std::string& num2){ + std::string larger, smaller; + + if (num1.size() > num2.size() || + (num1.size() == num2.size() && num1 > num2)) { + larger = num1; + smaller = num2; + } + else { + larger = num2; + smaller = num1; + } + + if(smaller[0] == '1'){ + smaller = std::string(larger.size() - smaller.size(), '1') + smaller; + } + else{ + smaller = std::string(larger.size() - smaller.size(), '0') + smaller; + } + + return std::make_tuple(larger, smaller); +} + /* BigInt & BigInt @@ -71,7 +138,7 @@ BigInt BigInt::operator&(const BigInt& num) const{ rhs_binary = to_binary(num); std::string larger, smaller; - std::tie(larger, smaller) = get_larger_and_smaller(lhs_binary, rhs_binary); + std::tie(larger, smaller) = sign_extend_binary(lhs_binary, rhs_binary); std::string complete_string; for(int i = 0; i < larger.size(); i++){ @@ -98,7 +165,7 @@ BigInt BigInt::operator|(const BigInt& num) const{ rhs_binary = to_binary(num); std::string larger, smaller; - std::tie(larger, smaller) = get_larger_and_smaller(lhs_binary, rhs_binary); + std::tie(larger, smaller) = sign_extend_binary(lhs_binary, rhs_binary); std::string complete_string; for(int i = 0; i < larger.size(); i++){ @@ -125,7 +192,7 @@ BigInt BigInt::operator^(const BigInt& num) const{ rhs_binary = to_binary(num); std::string larger, smaller; - std::tie(larger, smaller) = get_larger_and_smaller(lhs_binary, rhs_binary); + std::tie(larger, smaller) = sign_extend_binary(lhs_binary, rhs_binary); std::string complete_string; for(int i = 0; i < larger.size(); i++){