From dc234243c1be9e7cdc8777ea2201dccb6babc0d9 Mon Sep 17 00:00:00 2001 From: arenbecl Date: Tue, 15 Dec 2020 18:12:45 -0500 Subject: [PATCH 1/3] 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/3] 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 From 33ff01ee571ee6db568140e8a90ac6fd3f14a3cc Mon Sep 17 00:00:00 2001 From: GNL10 Date: Wed, 8 Feb 2023 00:04:17 +0000 Subject: [PATCH 3/3] Implemented tests for the bitwise methods --- CMakeLists.txt | 14 +++ include/operators/bitwise.hpp | 7 +- test/operators/bitwise.cpp | 135 ++++++++++++++++++++++ test/operators/bitwise_assignment.cpp | 159 ++++++++++++++++++++++++++ 4 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 test/operators/bitwise.cpp create mode 100644 test/operators/bitwise_assignment.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f658b16..47b2365 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,14 @@ add_executable(OperatorsUnaryArithmeticTest test/operators/unary_arithmetic.cpp) target_link_libraries(OperatorsUnaryArithmeticTest TestRunner) +add_executable(OperatorsBitwiseTest + test/operators/bitwise.cpp) +target_link_libraries(OperatorsBitwiseTest TestRunner) + +add_executable(OperatorsBitwiseAssignmentTest + test/operators/bitwise_assignment.cpp) +target_link_libraries(OperatorsBitwiseAssignmentTest TestRunner) + if(ENABLE_COVERAGE) # Include code coverage module list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake") @@ -83,6 +91,8 @@ if(ENABLE_COVERAGE) add_coverage(OperatorsIOStreamTest) add_coverage(OperatorsRelationalTest) add_coverage(OperatorsUnaryArithmeticTest) + add_coverage(OperatorsBitwiseTest) + add_coverage(OperatorsBitwiseAssignmentTest) list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'" "'include/third_party/*'") coverage_evaluate() endif() @@ -110,3 +120,7 @@ add_test(NAME OperatorsRelationalTest COMMAND $) add_test(NAME OperatorsUnaryArithmeticTest COMMAND $) +add_test(NAME OperatorsBitwiseTest + COMMAND $) +add_test(NAME OperatorsBitwiseAssignmentTest + COMMAND $) diff --git a/include/operators/bitwise.hpp b/include/operators/bitwise.hpp index 0c5bfe5..a48b9b7 100644 --- a/include/operators/bitwise.hpp +++ b/include/operators/bitwise.hpp @@ -176,10 +176,15 @@ BigInt BigInt::operator~() const { { throw std::invalid_argument("Operator '~' is undefined on negative operand"); } + else if(*this == 0) + { + return 1; + } + BigInt operand = *this; BigInt result = 0; BigInt increment = 1; - + while (operand > 0) { bool lowest_bit = (operand % 2 == 1); diff --git a/test/operators/bitwise.cpp b/test/operators/bitwise.cpp new file mode 100644 index 0000000..c9b29a9 --- /dev/null +++ b/test/operators/bitwise.cpp @@ -0,0 +1,135 @@ +#include "constructors/constructors.hpp" +#include "operators/bitwise.hpp" +#include "operators/io_stream.hpp" + +#include "third_party/catch.hpp" + +/* Each of the following tests, is testing the following combinations for each operator: + * BigInt operator BigInt + * BigInt operator int + * BigInt operator String + * int operator BigInt + * String operator BigInt +*/ + +TEST_CASE("Testing bitwise operator<<", "[bitwise][operators]") { + REQUIRE(BigInt("6140368949894") << BigInt(3) == BigInt("49122951599152")); + REQUIRE(BigInt("6273765576300") << 5 == BigInt("200760498441600")); + REQUIRE(BigInt("-1795467965410") << "2" == BigInt("-7181871861640")); + REQUIRE(0 << BigInt(4) == BigInt(0)); + REQUIRE("5" << BigInt(90) == BigInt("6189700196426901374495621120")); + + REQUIRE_THROWS(BigInt(3) << BigInt("-999999")); + REQUIRE_THROWS(BigInt(3) << -1); + REQUIRE_THROWS(BigInt(3) << "-1000000000"); + REQUIRE_THROWS(5123 << BigInt(-123)); + REQUIRE_THROWS(97436586 << BigInt(-10)); +} + +TEST_CASE("Testing bitwise operator>>", "[bitwise][operators]") { + REQUIRE(BigInt("15622171914854") >> BigInt(10) == BigInt("15256027260")); + REQUIRE(BigInt("31583741872386") >> 15 == BigInt("963859310")); + REQUIRE(BigInt("63805774123473") >> "19" == BigInt("121699856")); + REQUIRE(0 >> BigInt(92) == BigInt(0)); + REQUIRE("4951760157141521099596496896978124" >> BigInt(92) == BigInt(1000000)); + + REQUIRE_THROWS(BigInt(4) >> BigInt(-999999)); + REQUIRE_THROWS(BigInt(4) >> -1); + REQUIRE_THROWS(BigInt(4) >> "-1000000000"); + REQUIRE_THROWS(6547 >> BigInt(-123)); + REQUIRE_THROWS("948721" >> BigInt(-10)); +} + +TEST_CASE("Testing bitwise operator|", "[bitwise][operators]") { + REQUIRE((BigInt(0xFFFFFFFFF) | BigInt(0x0)) == BigInt(0xFFFFFFFFF)); + REQUIRE((BigInt(0x0) | 0x0) == BigInt(0)); + REQUIRE((BigInt("85628857714193") | "171237465081264") == BigInt("246279160973233")); + REQUIRE((0xDADF88 | BigInt(0x1B)) == BigInt(0xDADF9B)); + REQUIRE(("12837034363005" | BigInt("769106842816")) == BigInt("12918638746877")); + + REQUIRE_THROWS(BigInt(8712) | BigInt(-128367)); + REQUIRE_THROWS(BigInt(-87623423) | BigInt(457)); + REQUIRE_THROWS(BigInt(-751623) | BigInt(-987354)); + + REQUIRE_THROWS(BigInt(2) | -1); + REQUIRE_THROWS(BigInt(-56408945) | 1); + REQUIRE_THROWS(BigInt(-127814856) | -1); + + REQUIRE_THROWS(BigInt(1) | "-1000000000"); + REQUIRE_THROWS(BigInt(-78) | "1"); + REQUIRE_THROWS(BigInt(-34257) | "-9819432484"); + + REQUIRE_THROWS(1 | BigInt(-123)); + REQUIRE_THROWS(-3364 | BigInt(981723)); + REQUIRE_THROWS(-3 | BigInt(-123)); + + REQUIRE_THROWS("98123" | BigInt(-10)); + REQUIRE_THROWS("-12" | BigInt(19023876)); + REQUIRE_THROWS("-12" | BigInt(-10)); +} + +TEST_CASE("Testing bitwise operator&", "[bitwise][operators]") { + REQUIRE((BigInt(0xFFFFFFFF) & BigInt(0xFFFFFFFF)) == BigInt(0xFFFFFFFF)); + REQUIRE((BigInt(0xFFFFFFFF) & 0x00000000) == BigInt(0x00000000)); + REQUIRE((BigInt("65739150692879") & "11760462922974") == BigInt("11553767227406")); + REQUIRE((0x00000000 & BigInt(0x00000000)) == BigInt(0x00000000)); + REQUIRE(("11893765337427" & BigInt("44122253886130")) == BigInt("8800438321170")); + + REQUIRE_THROWS(BigInt(5678) & BigInt(-831)); + REQUIRE_THROWS(BigInt(-1) & BigInt(1235)); + REQUIRE_THROWS(BigInt(-5462) & BigInt(-45367)); + + REQUIRE_THROWS(BigInt(1982374) & -1); + REQUIRE_THROWS(BigInt(-389475) & 9837123); + REQUIRE_THROWS(BigInt("-23458792789") & -1); + + REQUIRE_THROWS(BigInt(978345) & "-98712347968"); + REQUIRE_THROWS(BigInt(-3) & "28347"); + REQUIRE_THROWS(BigInt(-4756) & "-12378"); + + REQUIRE_THROWS(142376 & BigInt(-123)); + REQUIRE_THROWS(-367534 & BigInt(532845)); + REQUIRE_THROWS(-9234576123 & BigInt(-123)); + + REQUIRE_THROWS("236548" & BigInt(-10)); + REQUIRE_THROWS("-12" & BigInt(98273548746)); + REQUIRE_THROWS("-12" & BigInt(-10)); +} + +TEST_CASE("Testing bitwise operator^", "[bitwise][operators]") { + REQUIRE((BigInt(0xFFFFFFFF) ^ BigInt(0xFFFFFFFF)) == BigInt(0x00000000)); + REQUIRE((BigInt(0xFFFFFFFF) ^ 0x00000000) == BigInt(0xFFFFFFFF)); + REQUIRE((BigInt("65739150692879") ^ "11760462922974") == BigInt("54392079161041")); + REQUIRE((0x00000000 ^ BigInt(0x00000000)) == BigInt(0x00000000)); + REQUIRE(("11893765337427" ^ BigInt("44122253886130")) == BigInt("38415142581217")); + + REQUIRE_THROWS(BigInt(5678) ^ BigInt(-831)); + REQUIRE_THROWS(BigInt(-1) ^ BigInt(1235)); + REQUIRE_THROWS(BigInt(-5462) ^ BigInt(-45367)); + + REQUIRE_THROWS(BigInt(1982374) ^ -1); + REQUIRE_THROWS(BigInt(-389475) ^ 9837123); + REQUIRE_THROWS(BigInt("-23458792789") ^ -1); + + REQUIRE_THROWS(BigInt(978345) ^ "-98712347968"); + REQUIRE_THROWS(BigInt(-3) ^ "28347"); + REQUIRE_THROWS(BigInt(-4756) ^ "-12378"); + + REQUIRE_THROWS(142376 ^ BigInt(-123)); + REQUIRE_THROWS(-367534 ^ BigInt(532845)); + REQUIRE_THROWS(-9234576123 ^ BigInt(-123)); + + REQUIRE_THROWS("236548" ^ BigInt(-10)); + REQUIRE_THROWS("-12" ^ BigInt(98273548746)); + REQUIRE_THROWS("-12" ^ BigInt(-10)); +} + +TEST_CASE("Testing bitwise operator~", "[bitwise][operators]") { + REQUIRE(~BigInt(0x0) == BigInt(0x1)); + REQUIRE(~BigInt(0xFFFFFFFFFFFFFFF) == BigInt(0x0)); + REQUIRE(~BigInt(0x1) == BigInt(0x0)); + REQUIRE(~BigInt(0XF1BDA3DAE) == BigInt(0X0E425C251)); + REQUIRE(~BigInt("3327762959") == BigInt("967204336")); + + REQUIRE_THROWS(~BigInt("-40020825")); +} \ No newline at end of file diff --git a/test/operators/bitwise_assignment.cpp b/test/operators/bitwise_assignment.cpp new file mode 100644 index 0000000..a50e87d --- /dev/null +++ b/test/operators/bitwise_assignment.cpp @@ -0,0 +1,159 @@ +#include "constructors/constructors.hpp" +#include "operators/bitwise.hpp" +#include "operators/bitwise_assignment.hpp" +#include "operators/io_stream.hpp" + +#include "third_party/catch.hpp" + +TEST_CASE("Testing bitwise operator<<=", "[bitwise][operators]") { + BigInt num1("6140368949894"); + BigInt num2("6273765576300"); + BigInt num3("-1795467965410"); + + REQUIRE((num1 <<= BigInt(3)) == BigInt("49122951599152")); + REQUIRE((num2 <<= 5) == BigInt("200760498441600")); + REQUIRE((num3 <<= "2") == BigInt("-7181871861640")); + + REQUIRE_THROWS((num1 <<= BigInt("-999999"))); + REQUIRE_THROWS((num2 <<= -1)); + REQUIRE_THROWS((num3 <<= "-1000000000")); +} + +TEST_CASE("Testing bitwise operator>>=", "[bitwise][operators]") { + BigInt num1("15622171914854"); + BigInt num2("31583741872386"); + BigInt num3("63805774123473"); + + REQUIRE((num1 >>= BigInt(10)) == BigInt("15256027260")); + REQUIRE((num2 >>= 15) == BigInt("963859310")); + REQUIRE((num3 >>= "19") == BigInt("121699856")); + + REQUIRE_THROWS((num1 >>= BigInt(-999999))); + REQUIRE_THROWS((num2 >>= -1)); + REQUIRE_THROWS((num3 >>= "-1000000000")); +} + +TEST_CASE("Testing bitwise operator|=", "[bitwise][operators]") { + { + BigInt num1(0xFFFFFFFFF); + BigInt num2(0x0); + BigInt num3("85628857714193"); + + REQUIRE((num1 |= BigInt(0x0)) == BigInt(0xFFFFFFFFF)); + REQUIRE((num2 |= 0x0) == BigInt(0)); + REQUIRE((num3 |= "171237465081264") == BigInt("246279160973233")); + } + + { + BigInt num1(8712); + BigInt num2(-87623423); + BigInt num3(-751623); + + REQUIRE_THROWS(num1 |= BigInt(-128367)); + REQUIRE_THROWS(num2 |= BigInt(457)); + REQUIRE_THROWS(num3 |= BigInt(-987354)); + } + + { + BigInt num1(2) ; + BigInt num2(-56408945); + BigInt num3(-127814856); + + REQUIRE_THROWS(num1 |= -1); + REQUIRE_THROWS(num2 |= 1); + REQUIRE_THROWS(num3 |= -1); + } + + { + BigInt num1(1) ; + BigInt num2(-78); + BigInt num3(-34257); + REQUIRE_THROWS(num1 |= "-1000000000"); + REQUIRE_THROWS(num2 |= "1"); + REQUIRE_THROWS(num3 |= "-9819432484"); + } +} + +TEST_CASE("Testing bitwise operator&=", "[bitwise][operators]") { + { + BigInt num1(0xFFFFFFFF); + BigInt num2(0xFFFFFFFF); + BigInt num3("65739150692879"); + + REQUIRE((num1 &= BigInt(0xFFFFFFFF)) == BigInt(0xFFFFFFFF)); + REQUIRE((num2 &= 0x00000000) == BigInt(0x00000000)); + REQUIRE((num3 &= "11760462922974") == BigInt("11553767227406")); + } + + { + BigInt num1(5678); + BigInt num2(-1); + BigInt num3(-5462); + + REQUIRE_THROWS(num1 &= BigInt(-831)); + REQUIRE_THROWS(num2 &= BigInt(1235)); + REQUIRE_THROWS(num3 &= BigInt(-45367)); + } + + { + BigInt num1(1982374); + BigInt num2(-389475); + BigInt num3("-23458792789"); + + REQUIRE_THROWS(num1 &= -1); + REQUIRE_THROWS(num2 &= 9837123); + REQUIRE_THROWS(num3 &= -1); + } + + { + BigInt num1(978345); + BigInt num2(-3); + BigInt num3(-4756); + + REQUIRE_THROWS(num1 &= "-98712347968"); + REQUIRE_THROWS(num2 &= "28347"); + REQUIRE_THROWS(num3 &= "-12378"); + } +} + +TEST_CASE("Testing bitwise operator^=", "[bitwise][operators]") { + { + BigInt num1(0xFFFFFFFFF); + BigInt num2(0x0); + BigInt num3("65739150692879"); + + REQUIRE((num1 ^= BigInt(0xFFFFFFFFF)) == BigInt(0x00000000)); + REQUIRE((num2 ^= 0x00000000) == BigInt(0x00000000)); + REQUIRE((num3 ^= "11760462922974") == BigInt("54392079161041")); + } + + { + BigInt num1(5678); + BigInt num2(-1); + BigInt num3(-5462); + + REQUIRE_THROWS(num1 ^= BigInt(-831)); + REQUIRE_THROWS(num2 ^= BigInt(1235)); + REQUIRE_THROWS(num3 ^= BigInt(-45367)); + } + + { + BigInt num1(1982374); + BigInt num2(-389475); + BigInt num3("-23458792789"); + + REQUIRE_THROWS(num1 ^= -1); + REQUIRE_THROWS(num2 ^= 9837123); + REQUIRE_THROWS(num3 ^= -1); + } + + { + BigInt num1(978345); + BigInt num2(-3); + BigInt num3(-4756); + + REQUIRE_THROWS(num1 ^= "-98712347968"); + REQUIRE_THROWS(num2 ^= "28347"); + REQUIRE_THROWS(num3 ^= "-12378"); + } +} \ No newline at end of file