From dc234243c1be9e7cdc8777ea2201dccb6babc0d9 Mon Sep 17 00:00:00 2001 From: arenbecl Date: Tue, 15 Dec 2020 18:12:45 -0500 Subject: [PATCH 1/2] Bitwise operators and bitwise assignment operators This pull adds the assignment operators for the bitwise operators open feature request, as well as my own take on the base operators. --- include/BigInt.hpp | 35 +++ include/operators/bitwise.hpp | 383 +++++++++++++++++++++++ include/operators/bitwise_assignment.hpp | 215 +++++++++++++ scripts/release.sh | 5 +- 4 files changed, 637 insertions(+), 1 deletion(-) create mode 100644 include/operators/bitwise.hpp create mode 100644 include/operators/bitwise_assignment.hpp diff --git a/include/BigInt.hpp b/include/BigInt.hpp index e3be86c..124e9ed 100644 --- a/include/BigInt.hpp +++ b/include/BigInt.hpp @@ -94,6 +94,41 @@ class BigInt { friend std::istream& operator>>(std::istream&, BigInt&); friend std::ostream& operator<<(std::ostream&, const BigInt&); + // Bitwise operators: + BigInt operator<<(const BigInt&) const; + BigInt operator>>(const BigInt&) const; + BigInt operator|(const BigInt&) const; + BigInt operator&(const BigInt&) const; + BigInt operator^(const BigInt&) const; + BigInt operator<<(const long long&) const; + BigInt operator>>(const long long&) const; + BigInt operator|(const long long&) const; + BigInt operator&(const long long&) const; + BigInt operator^(const long long&) const; + BigInt operator<<(const std::string&) const; + BigInt operator>>(const std::string&) const; + BigInt operator|(const std::string&) const; + BigInt operator&(const std::string&) const; + BigInt operator^(const std::string&) const; + BigInt operator~() const; + + //Bitwise assignment operators: + BigInt& operator<<=(const BigInt&); + BigInt& operator>>=(const BigInt&); + BigInt& operator|=(const BigInt&); + BigInt& operator&=(const BigInt&); + BigInt& operator^=(const BigInt&); + BigInt& operator<<=(const long long&); + BigInt& operator>>=(const long long&); + BigInt& operator|=(const long long&); + BigInt& operator&=(const long long&); + BigInt& operator^=(const long long&); + BigInt& operator<<=(const std::string&); + BigInt& operator>>=(const std::string&); + BigInt& operator|=(const std::string&); + BigInt& operator&=(const std::string&); + BigInt& operator^=(const std::string&); + // Conversion functions: std::string to_string() const; int to_int() const; diff --git a/include/operators/bitwise.hpp b/include/operators/bitwise.hpp new file mode 100644 index 0000000..b5928bc --- /dev/null +++ b/include/operators/bitwise.hpp @@ -0,0 +1,383 @@ +/* + =========================================================================== + Bitwise operators + =========================================================================== +*/ + +#ifndef BIG_INT_BITWISE_OPERATORS_HPP +#define BIG_INT_BITWISE_OPERATORS_HPP + +#include +#include +#include +#include "operators/arithmetic_assignment.hpp" +#include "operators/assignment.hpp" +#include "operators/binary_arithmetic.hpp" +#include "operators/relational.hpp" + + +#include "BigInt.hpp" + +/* + BigInt << BigInt + --------------- + Performs a bitwise shift left by the value of the RHS of the operation +*/ + +BigInt BigInt::operator<<(const BigInt& rhs) const { + // Right hand side cannot be negative + if (rhs < 0) { + throw std::invalid_argument("Operator '<<' is undefined on negative right-hand argument"); + } + BigInt mult = BigInt(1); + for (BigInt i = BigInt(0); i < rhs; i = i + 1) + { + mult *= 2; + } + return *this * BigInt(mult); +} + +/* + BigInt >> BigInt + --------------- + Performs a bitwise shift right by the value of the RHS of the operation +*/ + +BigInt BigInt::operator>>(const BigInt& rhs) const { + // Right hand side cannot be negative + if (rhs < 0) { + throw std::invalid_argument("Operator '>>' is undefined on negative right-hand argument"); + } + BigInt divisor = BigInt(1); + for (BigInt i = BigInt(0); i < rhs; i = i + 1) + { + divisor *= 2; + } + return *this / BigInt(divisor); +} + +/* + BigInt | BigInt + --------------- + Returns a BigInt with value equal to the bitwise OR of the binary representations of two positive operands +*/ + +BigInt BigInt::operator|(const BigInt& rhs) const { + // Neither side can be negative + if (rhs < 0) { + throw std::invalid_argument("Operator '|' is undefined on negative right-hand argument"); + } + if (*this < 0) + { + throw std::invalid_argument("Operator '|' is undefined on negative left-hand argument"); + } + BigInt left = *this; + BigInt right = rhs; + BigInt result = 0; + BigInt increment = 1; + + while (left > 0 || right > 0) + { + if ((left % 2 == 1) || (right % 2 == 1)) + { + result += increment; + } + increment *= 2; + left /= 2; + right /= 2; + } + return result; + +} + + +/* + BigInt & BigInt + --------------- + Returns a BigInt with value equal to the bitwise AND of the binary representations of two positive operands +*/ + +BigInt BigInt::operator&(const BigInt& rhs) const { + // Neither side can be negative + if (rhs < 0) { + throw std::invalid_argument("Operator '&' is undefined on negative right-hand argument"); + } + if (*this < 0) + { + throw std::invalid_argument("Operator '&' is undefined on negative left-hand argument"); + } + BigInt left = *this; + BigInt right = rhs; + BigInt result = 0; + BigInt increment = 1; + + while (left > 0 || right > 0) + { + if ((left % 2 == 1) && (right % 2 == 1)) + { + result += increment; + } + increment *= 2; + left /= 2; + right /= 2; + } + return result; + +} + + + +/* + BigInt ^ BigInt + --------------- + Returns a BigInt with value equal to the bitwise XOR of the binary representations of two positive operands +*/ + + +BigInt BigInt::operator^(const BigInt& rhs) const { + // Neither side can be negative + if (rhs < 0) { + throw std::invalid_argument("Operator '^' is undefined on negative right-hand argument"); + } + if (*this < 0) + { + throw std::invalid_argument("Operator '^' is undefined on negative left-hand argument"); + } + BigInt left = *this; + BigInt right = rhs; + BigInt result = 0; + BigInt increment = 1; + + while (left > 0 || right > 0) + { + bool left_bit = (left % 2 == 1); + bool right_bit = (right % 2 == 1); + if ((left_bit || right_bit) && (left_bit != right_bit)) + { + result += increment; + } + increment *= 2; + left /= 2; + right /= 2; + } + return result; + +} + + + +/* + ~BigInt + --------------- + Returns a BigInt with value equal to the bitwise NOT of the binary representations of the positive input +*/ + + +BigInt BigInt::operator~() const { + // Operand cannot be negative + if (*this < 0) + { + throw std::invalid_argument("Operator '~' is undefined on negative operand"); + } + BigInt operand = *this; + BigInt result = 0; + BigInt increment = 1; + + while (operand > 0) + { + bool lowest_bit = (operand % 2 == 1); + if (!lowest_bit) + { + result += increment; + } + increment *= 2; + operand /= 2; + } + return result; + +} + +/* + BigInt << int + --------------- +*/ + +BigInt BigInt::operator<<(const long long& rhs) const { + return *this << BigInt(rhs); +} + +/* + int << BigInt + --------------- +*/ + +BigInt operator<<(const long long& lhs, const BigInt& rhs) { + return BigInt(lhs) << rhs; +} + +/* + BigInt << String + --------------- +*/ + +BigInt BigInt::operator<<(const std::string& rhs) const { + return *this << BigInt(rhs); +} + +/* + String << BigInt + --------------- +*/ + +BigInt operator<<(const std::string& lhs, const BigInt& rhs) { + return BigInt(lhs) << rhs; +} + + +/* + BigInt >> int + --------------- +*/ + +BigInt BigInt::operator>>(const long long& rhs) const { + return *this >> BigInt(rhs); +} + +/* + int >> BigInt + --------------- +*/ + +BigInt operator>>(const long long& lhs, const BigInt& rhs) { + return BigInt(lhs) >> rhs; +} + +/* + BigInt >> String + --------------- +*/ + +BigInt BigInt::operator>>(const std::string& rhs) const { + return *this >> BigInt(rhs); +} + +/* + String >> BigInt + --------------- +*/ + +BigInt operator>>(const std::string& lhs, const BigInt& rhs) { + return BigInt(lhs) >> rhs; +} + + +/* + BigInt | int + --------------- +*/ + +BigInt BigInt::operator|(const long long& rhs) const { + return *this | BigInt(rhs); +} + +/* + int | BigInt + --------------- +*/ + +BigInt operator|(const long long& lhs, const BigInt& rhs) { + return BigInt(lhs) | rhs; +} + +/* + BigInt | String + --------------- +*/ + +BigInt BigInt::operator|(const std::string& rhs) const { + return *this | BigInt(rhs); +} + +/* + String | BigInt + --------------- +*/ + +BigInt operator|(const std::string& lhs, const BigInt& rhs) { + return BigInt(lhs) | rhs; +} + +/* + BigInt & int + --------------- +*/ + +BigInt BigInt::operator&(const long long& rhs) const { + return *this & BigInt(rhs); +} + +/* + int & BigInt + --------------- +*/ + +BigInt operator&(const long long& lhs, const BigInt& rhs) { + return BigInt(lhs) & rhs; +} + +/* + BigInt & String + --------------- +*/ + +BigInt BigInt::operator&(const std::string& rhs) const { + return *this & BigInt(rhs); +} + +/* + String & BigInt + --------------- +*/ + +BigInt operator&(const std::string& lhs, const BigInt& rhs) { + return BigInt(lhs) & rhs; +} + +/* + BigInt ^ int + --------------- +*/ + +BigInt BigInt::operator^(const long long& rhs) const { + return *this ^ BigInt(rhs); +} + +/* + int ^ BigInt + --------------- +*/ + +BigInt operator^(const long long& lhs, const BigInt& rhs) { + return BigInt(lhs) ^ rhs; +} + +/* + BigInt ^ String + --------------- +*/ + +BigInt BigInt::operator^(const std::string& rhs) const { + return *this ^ BigInt(rhs); +} + +/* + String ^ BigInt + --------------- +*/ + +BigInt operator^(const std::string& lhs, const BigInt& rhs) { + return BigInt(lhs) ^ rhs; +} + + +#endif // BIG_INT_BITWISE_OPERATORS_HPP diff --git a/include/operators/bitwise_assignment.hpp b/include/operators/bitwise_assignment.hpp new file mode 100644 index 0000000..2e0a0f1 --- /dev/null +++ b/include/operators/bitwise_assignment.hpp @@ -0,0 +1,215 @@ +/* + =========================================================================== + Bitwise assignment operators + =========================================================================== +*/ + +#ifndef BIG_INT_BITWISE_ASSIGNMENT_OPERATORS_HPP +#define BIG_INT_BITWISE_ASSIGNMENT_OPERATORS_HPP + + +#include "operators/bitwise.hpp" + + +#include "BigInt.hpp" + +/* + BigInt <<= BigInt + --------------- + Performs a bitwise shift left by the value of the RHS of the operation and assigns it +*/ + +BigInt& BigInt::operator<<=(const BigInt& rhs) { + *this = *this << rhs; + + return *this; +} + +/* + BigInt >>= BigInt + --------------- + Performs a bitwise shift left by the value of the RHS of the operation and assigns it +*/ + +BigInt& BigInt::operator>>=(const BigInt& rhs) { + *this = *this >> rhs; + + return *this; +} + +/* + BigInt |= BigInt + --------------- + Returns a BigInt with value equal to the bitwise OR of the binary representations of two positive operands and assigns it to the left operand +*/ + +BigInt& BigInt::operator|=(const BigInt& rhs) { + *this = *this | rhs; + + return *this; + +} + + +/* + BigInt &= BigInt + --------------- + Returns a BigInt with value equal to the bitwise AND of the binary representations of two positive operands and assigns it to the left operand +*/ + +BigInt& BigInt::operator&=(const BigInt& rhs) { + *this = *this & rhs; + + return *this; + +} + + + +/* + BigInt ^= BigInt + --------------- + Returns a BigInt with value equal to the bitwise XOR of the binary representations of two positive operands +*/ + + +BigInt& BigInt::operator^=(const BigInt& rhs) { + *this = *this ^ rhs; + + return *this; + +} + + + +/* + BigInt <<= int + --------------- +*/ + +BigInt& BigInt::operator<<=(const long long& rhs) { + *this = *this << rhs; + + return *this; +} + +/* + BigInt >>= int + --------------- +*/ + + + +BigInt& BigInt::operator>>=(const long long& rhs) { + *this = *this >> rhs; + + return *this; +} + +/* + BigInt |= int + --------------- +*/ + + +BigInt& BigInt::operator|=(const long long& rhs) { + *this = *this | rhs; + + return *this; + +} + + +/* + BigInt &= int + --------------- +*/ + + +BigInt& BigInt::operator&=(const long long& rhs) { + *this = *this & rhs; + + return *this; + +} + +/* + BigInt ^= int + --------------- +*/ + + + +BigInt& BigInt::operator^=(const long long& rhs) { + *this = *this ^ rhs; + + return *this; + +} + +/* + BigInt <<= string + --------------- +*/ + +BigInt& BigInt::operator<<=(const std::string& rhs) { + *this = *this << rhs; + + return *this; +} + +/* + BigInt >>= string + --------------- +*/ + + + +BigInt& BigInt::operator>>=(const std::string& rhs) { + *this = *this >> rhs; + + return *this; +} + +/* + BigInt |= string + --------------- +*/ + + +BigInt& BigInt::operator|=(const std::string& rhs) { + *this = *this | rhs; + + return *this; + +} + + +/* + BigInt &= string + --------------- +*/ + + +BigInt& BigInt::operator&=(const std::string& rhs) { + *this = *this & rhs; + + return *this; + +} + +/* + BigInt ^= string + --------------- +*/ + + + +BigInt& BigInt::operator^=(const std::string& rhs) { + *this = *this ^ rhs; + + return *this; + +} + +#endif // BIG_INT_BITWISE_ASSIGNMENT_OPERATORS_HPP diff --git a/scripts/release.sh b/scripts/release.sh index bc866bb..dcbaf88 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -38,7 +38,10 @@ header_files="BigInt.hpp \ operators/binary_arithmetic.hpp \ operators/arithmetic_assignment.hpp \ operators/increment_decrement.hpp \ - operators/io_stream.hpp" + operators/io_stream.hpp \ + operators/bitwise.hpp \ + operators/bitwise_assignment.hpp" + # append the contents of each header file to the release file for file in $header_files From 9be0f5af7fbd119401dbf2bcab66b3d9ff5bb00a Mon Sep 17 00:00:00 2001 From: arenbecl Date: Tue, 15 Dec 2020 18:24:05 -0500 Subject: [PATCH 2/2] Deleted extraneous whitespace Removed from the end of 13 various functions --- include/operators/bitwise.hpp | 6 +----- include/operators/bitwise_assignment.hpp | 15 +++------------ 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/include/operators/bitwise.hpp b/include/operators/bitwise.hpp index b5928bc..0c5bfe5 100644 --- a/include/operators/bitwise.hpp +++ b/include/operators/bitwise.hpp @@ -86,8 +86,7 @@ BigInt BigInt::operator|(const BigInt& rhs) const { left /= 2; right /= 2; } - return result; - + return result; } @@ -122,7 +121,6 @@ BigInt BigInt::operator&(const BigInt& rhs) const { right /= 2; } return result; - } @@ -161,7 +159,6 @@ BigInt BigInt::operator^(const BigInt& rhs) const { right /= 2; } return result; - } @@ -194,7 +191,6 @@ BigInt BigInt::operator~() const { operand /= 2; } return result; - } /* diff --git a/include/operators/bitwise_assignment.hpp b/include/operators/bitwise_assignment.hpp index 2e0a0f1..4902e4c 100644 --- a/include/operators/bitwise_assignment.hpp +++ b/include/operators/bitwise_assignment.hpp @@ -47,7 +47,6 @@ BigInt& BigInt::operator|=(const BigInt& rhs) { *this = *this | rhs; return *this; - } @@ -60,8 +59,7 @@ BigInt& BigInt::operator|=(const BigInt& rhs) { BigInt& BigInt::operator&=(const BigInt& rhs) { *this = *this & rhs; - return *this; - + return *this; } @@ -77,7 +75,6 @@ BigInt& BigInt::operator^=(const BigInt& rhs) { *this = *this ^ rhs; return *this; - } @@ -116,7 +113,6 @@ BigInt& BigInt::operator|=(const long long& rhs) { *this = *this | rhs; return *this; - } @@ -130,7 +126,6 @@ BigInt& BigInt::operator&=(const long long& rhs) { *this = *this & rhs; return *this; - } /* @@ -144,7 +139,6 @@ BigInt& BigInt::operator^=(const long long& rhs) { *this = *this ^ rhs; return *this; - } /* @@ -180,8 +174,7 @@ BigInt& BigInt::operator>>=(const std::string& rhs) { BigInt& BigInt::operator|=(const std::string& rhs) { *this = *this | rhs; - return *this; - + return *this; } @@ -195,7 +188,6 @@ BigInt& BigInt::operator&=(const std::string& rhs) { *this = *this & rhs; return *this; - } /* @@ -208,8 +200,7 @@ BigInt& BigInt::operator&=(const std::string& rhs) { BigInt& BigInt::operator^=(const std::string& rhs) { *this = *this ^ rhs; - return *this; - + return *this; } #endif // BIG_INT_BITWISE_ASSIGNMENT_OPERATORS_HPP