diff --git a/bigint.h b/bigint.h index 86d1b88..9a7035a 100644 --- a/bigint.h +++ b/bigint.h @@ -41,36 +41,33 @@ #include namespace BigInt { - - class bigint { + class bigint + { public: // LLONG_MAX = 9'223'372'036'854'775'807 static constexpr auto MAX_SIZE = 1'000'000'000'000'000'000LL; - bigint() {is_neg = false; vec.emplace_back(0);} + bigint() : vec({0}) {} - bigint(const std::string &s) - { - if (!is_bigint(s)) {throw std::runtime_error("Invalid Big Integer.");} - if(s[0] == '-') - { + bigint(const std::string& s) { + if (!is_bigint(s)) { throw std::runtime_error("Invalid Big Integer."); } + if (s[0] == '-') { *this = bigint(s.substr(1)); if (*this == 0) throw std::runtime_error("Invalid Big Integer."); is_neg = true; } - else - { + else { + is_neg = false; vec = string_to_vector(s); } } - bigint(const char c) - { - int temp = static_cast(c); - if (isdigit(temp)) { + bigint(const char c) { + if (const int temp = static_cast(c); isdigit(temp)) { *this = bigint(char_to_int(c)); - } else { + } + else { throw std::runtime_error("Invalid Big Integer has been fed."); } } @@ -83,18 +80,14 @@ namespace BigInt { bigint(const double n) : bigint(static_cast(n)) {} - bigint(const long long n) { - if (n == 0) - { + bigint(const long long n): is_neg(n < 0) { + if (n == 0) { is_neg = false; vec.push_back(0); return; } - is_neg = (n<0); - unsigned long long val = n; - if (is_neg) - { + if (is_neg) { val = 0ULL - val; } vec.reserve(2); @@ -107,25 +100,26 @@ namespace BigInt { } bigint(unsigned long long n) { - - if ( n >= MAX_SIZE ) - { - vec.emplace_back(n / MAX_SIZE); - vec.emplace_back(n % MAX_SIZE); - } - else{ - vec.emplace_back(n); - } + if (n >= MAX_SIZE) { + vec.emplace_back(n / MAX_SIZE); + vec.emplace_back(n % MAX_SIZE); + } + else { + vec.emplace_back(n); + } } - bigint(const bigint &n) { *this = n; } + bigint(const bigint& n) = default; bigint(const char* n) : bigint(std::string(n)) {} - bigint(std::vector n) {this->vec = std::move(n);} + /* If initializing from a vector that should be negative, the negative value must be set afterward. + * bigint alpha(std::vector(...)); + * -alpha; + */ + bigint(std::vector n) : vec(std::move(n)) {} - bigint& operator=(const bigint& other) - { + bigint& operator=(const bigint& other) { if (this == &other) return *this; this->is_neg = other.is_neg; @@ -134,162 +128,151 @@ namespace BigInt { return *this; } - explicit operator int() const - { + explicit operator int() const { return static_cast(vec.back()); } - explicit operator long long() const - { - return vec.back(); + explicit operator long long() const { + return vec.back(); } - explicit operator std::string() const - { - return (this->is_neg ? "-" : "") + vector_to_string(this->vec); + explicit operator std::string() const { + return (this->is_neg ? "-" : "") + vector_to_string(this->vec); } - friend std::ostream &operator<<(std::ostream &stream, const bigint &n) - { + friend std::ostream& operator<<(std::ostream& stream, const bigint& n) { stream << std::string(n); return stream; } - bigint operator+=(const bigint &rhs) - { + bigint operator+=(const bigint& rhs) { if (*this == 0 && rhs == 0) return *this; - if (*this == 0) {*this = rhs; return *this;} + if (*this == 0) { + *this = rhs; + return *this; + } if (rhs != 0) { *this = add(*this, rhs); } return *this; } - bigint operator+(const bigint &rhs) const - { + bigint operator+(const bigint& rhs) const { bigint result = *this; result += rhs; return result; } - bigint operator-=(const bigint &rhs) - { + bigint operator-=(const bigint& rhs) { + if (rhs == 0) { return *this; } + if (*this == rhs) { + *this = 0; + return *this; + } *this = subtract(*this, rhs); return *this; } - bigint operator-(const bigint &rhs) const - { + bigint operator-(const bigint& rhs) const { bigint result = *this; result -= rhs; return result; } - bigint operator*=(const bigint &rhs) - { + bigint operator*=(const bigint& rhs) { *this = multiply(*this, rhs); return *this; } - bigint operator*(const bigint &rhs) const - { + bigint operator*(const bigint& rhs) const { bigint result = *this; result *= rhs; return result; } - bigint &operator/=(const bigint &rhs) - { + bigint& operator/=(const bigint& rhs) { *this = divide(*this, rhs); return *this; } - bigint operator/(const bigint &rhs) const - { + bigint operator/(const bigint& rhs) const { bigint result = *this; result /= rhs; return result; } - bigint operator%=(const bigint &rhs) - { + bigint operator%=(const bigint& rhs) { *this = mod(*this, rhs); return *this; } - bigint operator%(const bigint &rhs) const - { + bigint operator%(const bigint& rhs) const { bigint result = *this; result %= rhs; return result; } - bigint operator++() - { + bigint operator++() { *this += 1; return *this; } - bigint operator++(int) - { + bigint operator++(int) { bigint tmp(*this); operator++(); return tmp; } - bigint operator--() - { + bigint operator--() { *this -= 1; return *this; } - bigint operator--(int) - { + bigint operator--(int) { bigint tmp(*this); operator--(); return tmp; } - bigint operator-() const & - { + bigint operator-() const & { bigint temp = *this; if (temp == 0) return temp; temp.is_neg = !this->is_neg; return temp; } - bigint operator-() && - { + bigint operator-() && { if (*this == 0) return *this; this->is_neg = !this->is_neg; return *this; } - friend bool operator==(const bigint &l, const bigint &r) - { - if (l.is_neg != r.is_neg) - { + friend bool operator==(const bigint& l, const bigint& r) { + if (l.is_neg != r.is_neg) { return false; } return l.vec == r.vec; } - friend bool operator!=(const bigint &l, const bigint &r) - { return !(l == r); } + friend bool operator!=(const bigint& l, const bigint& r) { + return !(l == r); + } - friend bool operator<(const bigint &lhs, const bigint &rhs) - { + friend bool operator<(const bigint& lhs, const bigint& rhs) { return less_than(lhs, rhs); } - friend bool operator>(const bigint &l, const bigint &r) - { return r < l; } + friend bool operator>(const bigint& l, const bigint& r) { + return r < l; + } - friend bool operator<=(const bigint &l, const bigint &r) - { return r >= l; } + friend bool operator<=(const bigint& l, const bigint& r) { + return r >= l; + } - friend bool operator>=(const bigint &l, const bigint &r) - { return !(l < r); } + friend bool operator>=(const bigint& l, const bigint& r) { + return !(l < r); + } explicit operator bool() const { return !(vec.size() == 1 && vec.front() == 0); @@ -297,28 +280,24 @@ namespace BigInt { friend std::hash; - static bigint pow(const bigint &base, const bigint &exponent) - { + static bigint pow(const bigint& base, const bigint& exponent) { if (exponent == 0) return 1; if (exponent == 1) return base; const bigint tmp = pow(base, exponent / 2); - if (exponent % 2 == 0) {return tmp * tmp;} + if (exponent % 2 == 0) { return tmp * tmp; } return base * tmp * tmp; } - static bigint maximum(const bigint &lhs, const bigint &rhs) - { + static bigint maximum(const bigint& lhs, const bigint& rhs) { return lhs > rhs ? lhs : rhs; } - static bigint minimum(const bigint &lhs, const bigint &rhs) - { + static bigint minimum(const bigint& lhs, const bigint& rhs) { return lhs > rhs ? rhs : lhs; } - static bigint abs(const bigint &s) - { + static bigint abs(const bigint& s) { if (!is_negative(s)) return s; bigint temp = s; @@ -327,49 +306,44 @@ namespace BigInt { return temp; } - static bigint abs(bigint&& s) - { + static bigint abs(bigint&& s) { s.is_neg = false; return s; } - static bigint sqrt(const bigint &); + static bigint sqrt(const bigint&); - static bigint log2(const bigint &); + static bigint log2(const bigint&); - static bigint log10(const bigint &); + static bigint log10(const bigint&); - static bigint logwithbase(const bigint &, const bigint &); + static bigint logwithbase(const bigint&, const bigint&); - static bigint antilog2(const bigint &); + static bigint antilog2(const bigint&); - static bigint antilog10(const bigint &); + static bigint antilog10(const bigint&); - static void swap(bigint &, bigint &); + static void swap(bigint&, bigint&); - static bigint gcd(const bigint &, const bigint &); + static bigint gcd(const bigint&, const bigint&); - static bigint lcm(const bigint &lhs, const bigint &rhs) - { + static bigint lcm(const bigint& lhs, const bigint& rhs) { return (lhs * rhs) / gcd(lhs, rhs); } - static bigint factorial(const bigint &); + static bigint factorial(const bigint&); - static bool is_even(const bigint &input) - { + static bool is_even(const bigint& input) { return !(input.vec.back() & 1); } - static bool is_negative(const bigint &input) - { + static bool is_negative(const bigint& input) { return input.is_neg; } - static bool is_prime(const bigint &); + static bool is_prime(const bigint&); - static bigint sum_of_digits(const bigint& input) - { + static bigint sum_of_digits(const bigint& input) { bigint sum; for (auto base : input.vec) { for (sum = 0; base > 0; sum += base % 10, base /= 10); @@ -389,8 +363,9 @@ namespace BigInt { static bigint random(size_t length); private: - std::vector vec{}; bool is_neg{false}; + std::vector vec; + // Function Definitions for Internal Uses @@ -409,17 +384,16 @@ namespace BigInt { static std::string vector_to_string(const std::vector& input); - static bigint add(const bigint &, const bigint &); + static bigint add(const bigint&, const bigint&); - static bigint subtract(const bigint &, const bigint &); + static bigint subtract(const bigint&, const bigint&); - static bigint multiply(const bigint &, const bigint &); + static bigint multiply(const bigint&, const bigint&); - static bigint divide(const bigint &, const bigint &); + static bigint divide(const bigint&, const bigint&); - static bigint mod(const bigint &lhs, const bigint &rhs) - { - if (rhs == 0) {throw std::domain_error("Attempted to modulo by zero.");} + static bigint mod(const bigint& lhs, const bigint& rhs) { + if (rhs == 0) { throw std::domain_error("Attempted to modulo by zero."); } if (lhs < rhs) { return lhs; } @@ -427,55 +401,46 @@ namespace BigInt { return 0; } - if (rhs == 2) - { + if (rhs == 2) { return !is_even(lhs); } return lhs - ((lhs / rhs) * rhs); } - static bool is_bigint(const std::string &); + static bool is_bigint(const std::string&); static int count_digits(const bigint&); - static int char_to_int(const char input) - { + static int char_to_int(const char input) { return input - '0'; } - static int int_to_char(const int input) - { + static int int_to_char(const int input) { return input + '0'; } - static bigint negate(const bigint& input) - { + static bigint negate(const bigint& input) { bigint temp = input; temp.is_neg = !temp.is_neg; return temp; } - static bigint negate(bigint&& input) - { + static bigint negate(bigint&& input) { input.is_neg = !input.is_neg; return input; } - static bool less_than(const bigint& lhs, const bigint& rhs) - { - if (is_negative(lhs) && is_negative(rhs)) - { + static bool less_than(const bigint& lhs, const bigint& rhs) { + if (is_negative(lhs) && is_negative(rhs)) { return less_than(abs(rhs), abs(lhs)); } - if (is_negative(lhs) || is_negative(rhs)) - { + if (is_negative(lhs) || is_negative(rhs)) { return is_negative(lhs); } - if(lhs.vec.size() == rhs.vec.size()) - { + if (lhs.vec.size() == rhs.vec.size()) { return lhs.vec < rhs.vec; } @@ -484,8 +449,7 @@ namespace BigInt { }; - inline bool bigint::is_bigint(const std::string &s) - { + inline bool bigint::is_bigint(const std::string& s) { if (s.empty() || (s.length() > 1 && s[0] == '0')) return false; @@ -495,8 +459,7 @@ namespace BigInt { return s.find_first_not_of("0123456789", 0) == std::string::npos; } - inline bigint bigint::add(const bigint &lhs, const bigint &rhs) - { + inline bigint bigint::add(const bigint& lhs, const bigint& rhs) { bool negate_answer = false; // Ensure both are positive if (is_negative(lhs) && is_negative(rhs)) negate_answer = true; @@ -524,7 +487,8 @@ namespace BigInt { if (sum >= MAX_SIZE) { sum -= MAX_SIZE; carry = 1; - } else { + } + else { carry = 0; } @@ -537,102 +501,85 @@ namespace BigInt { } std::reverse(result.begin(), result.end()); - bigint result_bigint {std::move(result)}; + bigint result_bigint{std::move(result)}; return negate_answer ? negate(result_bigint) : result_bigint; } - inline std::pair subtract_with_borrow(const long long lhs, const long long rhs) - { - if (lhs < rhs) - { - // Borrow needs to happen - auto result = (lhs + bigint::MAX_SIZE) - rhs; - return {1, result}; // 1 represents a borrow - } - - auto result = lhs - rhs; - return {0, result}; // 0 means no borrow - } - - inline bigint bigint::subtract(const bigint &lhs, const bigint &rhs) - { + inline bigint bigint::subtract(const bigint& lhs, const bigint& rhs) { // Ensure LHS is larger than RHS, and both are positive - if (rhs == 0) return lhs; - if (lhs == rhs) return 0; - - if (is_negative(lhs) && is_negative(rhs)) - { + // (-A) - (-B) == B - A + if (is_negative(lhs) && is_negative(rhs)) { return subtract(abs(rhs), abs(lhs)); } - if (is_negative(rhs)) - { + // (A) - (-B) == A + B + if (is_negative(rhs)) { return add(lhs, abs(rhs)); } - if (is_negative(lhs)) - { - return add(lhs, negate(rhs)); + // (-A) - (B) == -(A + B) + if (is_negative(lhs)) { + return negate(add(abs(lhs), rhs)); } - if (lhs < rhs) - { + if (lhs < rhs) { return negate(subtract(rhs, lhs)); } - bigint full_rhs = rhs; - std::vector> borrow_result(lhs.vec.size()); - // Fill the smaller to match the larger size - while (lhs.vec.size() > full_rhs.vec.size()) - { - full_rhs.vec.insert(full_rhs.vec.begin(), 0); - } + std::vector result; + result.reserve(lhs.vec.size()); + long long borrow = 0; - std::transform(lhs.vec.rbegin(), lhs.vec.rend(), full_rhs.vec.rbegin(), borrow_result.rbegin(), - subtract_with_borrow); + auto it_l = lhs.vec.rbegin(); + auto it_r = rhs.vec.rbegin(); - std::vector final(lhs.vec.size()); - for (int i = borrow_result.size() - 1; i >= 0; --i) { - final[i] += borrow_result[i].second; - if (borrow_result[i].first) - final[i - 1] -= borrow_result[i].first; - } + while (it_l != lhs.vec.rend()) { + const long long l_val = *it_l; + const long long r_val = (it_r != rhs.vec.rend()) ? *it_r : 0; + + long long diff = l_val - r_val - borrow; + if (diff < 0) { + diff += MAX_SIZE; + borrow = 1; + } + else { + borrow = 0; + } + result.push_back(diff); - return trim(final); + ++it_l; + if (it_r != rhs.vec.rend()) ++it_r; + } + std::reverse(result.begin(), result.end()); + return trim(bigint(std::move(result))); } - inline bigint bigint::multiply(const bigint &lhs, const bigint &rhs) - { + inline bigint bigint::multiply(const bigint& lhs, const bigint& rhs) { if (lhs == 0 || rhs == 0) return 0; if (lhs == 1) return rhs; if (rhs == 1) return lhs; - if (is_negative(lhs) && is_negative(rhs)) - { + if (is_negative(lhs) && is_negative(rhs)) { return (abs(lhs) * abs(rhs)); } - if (is_negative(lhs) || is_negative(rhs)) - { + if (is_negative(lhs) || is_negative(rhs)) { return negate(abs(lhs) * abs(rhs)); } - if (lhs < rhs) - { + if (lhs < rhs) { return multiply(rhs, lhs); } std::vector result(lhs.vec.size() + rhs.vec.size(), 0); - for (auto it_lhs = lhs.vec.rbegin(); it_lhs != lhs.vec.rend(); ++it_lhs) - { - for (auto it_rhs = rhs.vec.rbegin(); it_rhs != rhs.vec.rend(); ++it_rhs) - { + for (auto it_lhs = lhs.vec.rbegin(); it_lhs != lhs.vec.rend(); ++it_lhs) { + for (auto it_rhs = rhs.vec.rbegin(); it_rhs != rhs.vec.rend(); ++it_rhs) { // Calculate the product and the corresponding indices in the result vector // use 128 bits to carefully store overflow __int128 mul = static_cast<__int128>(*it_lhs) * static_cast<__int128>(*it_rhs); - auto pos_low_it = result.rbegin() + (std::distance(lhs.vec.rbegin(), it_lhs) + std::distance(rhs.vec.rbegin(), it_rhs)); + auto pos_low_it = result.rbegin() + (std::distance(lhs.vec.rbegin(), it_lhs) + std::distance( + rhs.vec.rbegin(), it_rhs)); auto pos_high_it = pos_low_it + 1; // Add the product to the result vector *pos_low_it += mul % MAX_SIZE; - if (pos_high_it != result.rend()) - { + if (pos_high_it != result.rend()) { *pos_high_it += mul / MAX_SIZE; } @@ -648,8 +595,7 @@ namespace BigInt { // Handle carries for remaining positions for (auto r_iter = result.rbegin(); r_iter != result.rend() - 1; ++r_iter) { - if (*r_iter >= MAX_SIZE) - { + if (*r_iter >= MAX_SIZE) { *(r_iter + 1) += *r_iter / MAX_SIZE; *r_iter %= MAX_SIZE; } @@ -659,30 +605,24 @@ namespace BigInt { } - inline bigint bigint::divide(const bigint &numerator, const bigint &denominator) - { - if (denominator == 0) - { + inline bigint bigint::divide(const bigint& numerator, const bigint& denominator) { + if (denominator == 0) { throw std::domain_error("Attempted to divide by zero."); } if (numerator == denominator) return 1; if (denominator == 1) return numerator; if (numerator == 0) return 0; - if (is_negative(numerator) && is_negative(denominator)) - { + if (is_negative(numerator) && is_negative(denominator)) { return divide(abs(numerator), abs(denominator)); } - if (is_negative(numerator) || is_negative(denominator)) - { + if (is_negative(numerator) || is_negative(denominator)) { return negate(divide(abs(numerator), abs(denominator))); } - if (numerator < denominator) - { + if (numerator < denominator) { return 0; } - if (numerator.vec.size() <= 1) - { + if (numerator.vec.size() <= 1) { return numerator.vec.back() / denominator.vec.back(); } @@ -695,21 +635,18 @@ namespace BigInt { auto temp = denominator * numerator_size; - while (denominator * numerator_size < remainder) - { + while (denominator * numerator_size < remainder) { temp = denominator * numerator_size; remainder -= temp; quotient += numerator_size; count = count_digits(remainder) - count_digits(denominator) - 1; - if (numerator_size <= 1) - { + if (numerator_size <= 1) { quotient += remainder / denominator; break; } - if (remainder.vec.size() <= 1) - { + if (remainder.vec.size() <= 1) { quotient += remainder.vec.back() / denominator.vec.back(); break; } @@ -719,8 +656,7 @@ namespace BigInt { return quotient; } - inline bigint bigint::sqrt(const bigint &input) - { + inline bigint bigint::sqrt(const bigint& input) { if (is_negative(input)) throw std::domain_error("Square root of a negative number is complex"); @@ -741,7 +677,8 @@ namespace BigInt { if (square < input) { low_end = mid_point + 1; answer = mid_point; - } else { + } + else { high_end = mid_point - 1; } } @@ -749,8 +686,7 @@ namespace BigInt { } - inline bigint bigint::log2(const bigint &input) - { + inline bigint bigint::log2(const bigint& input) { if (is_negative(input) || input == 0) throw std::domain_error("Invalid input for natural log"); @@ -768,16 +704,15 @@ namespace BigInt { return exponent; // TODO: Convert to using division after checking bigO of division vs multiplication -// std::string logVal = "-1"; -// while(s != "0") { -// logVal = add(logVal, "1"); -// s = divide(s, "2"); -// } -// return logVal; + // std::string logVal = "-1"; + // while(s != "0") { + // logVal = add(logVal, "1"); + // s = divide(s, "2"); + // } + // return logVal; } - inline bigint bigint::log10(const bigint &input) - { + inline bigint bigint::log10(const bigint& input) { if (is_negative(input) || input == 0) throw std::domain_error("Invalid input for log base 10"); @@ -795,33 +730,28 @@ namespace BigInt { return count - 1; } - inline bigint bigint::logwithbase(const bigint &input, const bigint &base) - { + inline bigint bigint::logwithbase(const bigint& input, const bigint& base) { auto top = log2(input); auto bottom = log2(base); auto answer = divide(top, bottom); return answer; } - inline bigint bigint::antilog2(const bigint &input) - { + inline bigint bigint::antilog2(const bigint& input) { return pow(2, input); } - inline bigint bigint::antilog10(const bigint &input) - { + inline bigint bigint::antilog10(const bigint& input) { return pow(10, input); } - inline void bigint::swap(bigint &lhs, bigint &rhs) - { + inline void bigint::swap(bigint& lhs, bigint& rhs) { const bigint temp = lhs; lhs = rhs; rhs = temp; } - inline bigint bigint::gcd(const bigint &lhs, const bigint &rhs) - { + inline bigint bigint::gcd(const bigint& lhs, const bigint& rhs) { bigint temp_l = lhs, temp_r = rhs, remainder; if (rhs > lhs) swap(temp_l, temp_r); @@ -834,8 +764,7 @@ namespace BigInt { return temp_l; } - inline bigint bigint::factorial(const bigint &input) - { + inline bigint bigint::factorial(const bigint& input) { if (is_negative(input)) { throw std::runtime_error("Factorial of Negative Integer is not defined."); } @@ -851,8 +780,9 @@ namespace BigInt { return ans; } - inline bool bigint::is_prime(const bigint &s) - { + /* Simplest form of prime checking, implement your own + */ + inline bool bigint::is_prime(const bigint& s) { if (is_negative(s) || s == 1) return false; @@ -862,9 +792,7 @@ namespace BigInt { if (is_even(s) || s % 5 == 0) return false; - - bigint i; - for (i = 3; i * i <= s; i += 2) { + for (bigint i = 3; i * i <= s; i += 2) { if ((s % i) == 0) { return false; } @@ -904,13 +832,11 @@ namespace BigInt { constexpr int chunk_size = 18; const int size = input.size(); - if (size > chunk_size) - { + if (size > chunk_size) { // Pad the length to get appropriate sized chunks input.insert(0, chunk_size - (size % chunk_size), '0'); } - for (int i = 0; i < input.size(); i+=chunk_size) - { + for (int i = 0; i < input.size(); i += chunk_size) { std::string temp_str = input.substr(i, chunk_size); result.emplace_back(stoll(temp_str)); } @@ -923,33 +849,36 @@ namespace BigInt { bool first = true; for (auto partial : input) { if (first) { - ss << partial; // No padding for the first number + ss << partial; // No padding for the first number first = false; - } else { - ss << std::setw(18) << std::setfill('0') << partial; // Pad to 18 digits + } + else { + ss << std::setw(18) << std::setfill('0') << partial; // Pad to 18 digits } } return ss.str(); } - inline int bigint::count_digits(const bigint & input) { + inline int bigint::count_digits(const bigint& input) { std::string my_string = vector_to_string(input.vec); return static_cast(my_string.length()) - 1; } - } // namespace::BigInt template<> -struct std::hash { - std::size_t operator()(const BigInt::bigint& input) const - { +struct std::hash +{ + std::size_t operator()(const BigInt::bigint& input) const { std::size_t seed = input.vec.size(); - for(auto x : input.vec) { + for (auto x : input.vec) { x = ((x >> 16) ^ x) * 0x45d9f3b; x = ((x >> 16) ^ x) * 0x45d9f3b; x = (x >> 16) ^ x; seed ^= x + 0x9e3779b9 + (seed << 6) + (seed >> 2); } + if (input.is_neg) { + seed ^= 0x9e3779b9 + (seed << 6) + (seed >> 2); + } return seed; } }; diff --git a/tests/test.cpp b/tests/test.cpp index 034b62b..041a796 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../bigint.h" @@ -20,16 +21,24 @@ using std::chrono::duration_cast; bool SKIP_PERFORMANCE_TESTS = false; constexpr std::string_view kNines = "9999999999999999999"; -constexpr std::string_view kHugeA = "37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291592993232666589290350588973179516741959648948892906581313716663682087787058913539002195482835009516853"; -constexpr std::string_view kHugeB = "9843174278608822755442867695930794030260633344831664962118526669621620352474231493840674921513269404"; - -constexpr std::string_view AplusB = "37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291602836406945198113106031840875447535989909582237738246275835190351709407411387770496036157756522786257"; -constexpr std::string_view AminusB = "37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291583150058387980467595146105483585947929388315548074916351598137012466166706439307508354807913496247449"; -constexpr std::string_view AmulB = "371522673656074543721939903145636335168668810492059508909919665306024609291590328396789563611909881956692074164896572222014925589282684907671824165394055196075714622557089856059685618270608317568409327841248791007327091177305027733796385625358604009972642833675600135432852203678357550499911005775538860759946390549681453248681292307393576029610404491475299486834429621773400380504580240368032838923535804505697336440062521338464979118468824407819968770248251010402682462172033117899977017721981977515651526349027968047250058213343537761879103544485699067309526235122799512472963309861508662467265612"; -constexpr std::string_view AdivB = "3834555025961928452480859540164628181402139687101087313422864247768110206281588207268817088767383084425857331782324292423438870254834351784862584845557954696973368973237622555423975476296891710599837880699585094449938105117601882807098249270619115466337592065938882369152755194714547350194277427676672295574028506048275631567039158386540348169130522428891371330855740227809243175650789881054423775986"; -constexpr std::string_view AmodB = "2156048695288816089284014643351839933776226311026153430599415874278141145999872948608252665245784509"; - -constexpr std::string_view BminusA = "-37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291583150058387980467595146105483585947929388315548074916351598137012466166706439307508354807913496247449"; +constexpr std::string_view kHugeA = + "37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291592993232666589290350588973179516741959648948892906581313716663682087787058913539002195482835009516853"; +constexpr std::string_view kHugeB = + "9843174278608822755442867695930794030260633344831664962118526669621620352474231493840674921513269404"; + +constexpr std::string_view AplusB = + "37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291602836406945198113106031840875447535989909582237738246275835190351709407411387770496036157756522786257"; +constexpr std::string_view AminusB = + "37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291583150058387980467595146105483585947929388315548074916351598137012466166706439307508354807913496247449"; +constexpr std::string_view AmulB = + "371522673656074543721939903145636335168668810492059508909919665306024609291590328396789563611909881956692074164896572222014925589282684907671824165394055196075714622557089856059685618270608317568409327841248791007327091177305027733796385625358604009972642833675600135432852203678357550499911005775538860759946390549681453248681292307393576029610404491475299486834429621773400380504580240368032838923535804505697336440062521338464979118468824407819968770248251010402682462172033117899977017721981977515651526349027968047250058213343537761879103544485699067309526235122799512472963309861508662467265612"; +constexpr std::string_view AdivB = + "3834555025961928452480859540164628181402139687101087313422864247768110206281588207268817088767383084425857331782324292423438870254834351784862584845557954696973368973237622555423975476296891710599837880699585094449938105117601882807098249270619115466337592065938882369152755194714547350194277427676672295574028506048275631567039158386540348169130522428891371330855740227809243175650789881054423775986"; +constexpr std::string_view AmodB = + "2156048695288816089284014643351839933776226311026153430599415874278141145999872948608252665245784509"; + +constexpr std::string_view BminusA = + "-37744193401458640707539380267899264828998907634573602318662036836618621958669475225851195876029606479769348216875016014259295382637670116067802415326896673540817149305648020275612344553440582481192266196913778504499507839960073829863258118424953008896871971652295554512459916848335206655076766027606195514199793888542571641680917367253163346581387963223123048507895574406540841752099433832902520291583150058387980467595146105483585947929388315548074916351598137012466166706439307508354807913496247449"; struct TestCase { @@ -37,10 +46,11 @@ struct TestCase std::string rhs; std::string expected; - TestCase(const std::string_view lhs, const std::string_view rhs, const std::string_view expected) : lhs(lhs), rhs(rhs), expected(expected) {} + TestCase(const std::string_view lhs, const std::string_view rhs, + const std::string_view expected) : lhs(lhs), rhs(rhs), expected(expected) {} }; -class Test_BigInt : public ::testing::Test{}; +class Test_BigInt : public ::testing::Test {}; static auto formatTime = [](const long long micros) -> std::string { if (micros >= 1000000) return std::to_string(micros / 1000000.0) + " s"; @@ -56,17 +66,18 @@ static auto measure_execution = [](const int count, const char* label, const siz const long long duration = duration_cast(t2 - t1).count(); const double avg_per_op = static_cast(duration) / count; - std::cout << std::setw(14) << std::left << label << " [" << size << " digits]: " - << formatTime(duration) - << " (Avg: " << avg_per_op << " us/op)" << std::endl; + std::cout << std::setw(14) << std::left << label << " [" << size << " digits]: " + << formatTime(duration) + << " (Avg: " << avg_per_op << " us/op)" << std::endl; }; class Test_BigInt_Performance : public ::testing::Test { protected: static constexpr size_t number_count = 500; - const std::vector sizes = {5, 20, 50, 100, 1000, 10'000, 100'000}; + const std::vector sizes = {5, 20, 50, 100, 1000, 10'000, 100'000, 1'000'000}; volatile int dce_sink = 0; + void SetUp() override { if (SKIP_PERFORMANCE_TESTS) GTEST_SKIP() << "Skipping performance tests for this fixture"; @@ -76,9 +87,9 @@ class Test_BigInt_Performance : public ::testing::Test class Test_BigInt_F : public ::testing::Test { protected: - bigint A {std::string(kHugeA)}; - bigint B {std::string(kHugeB)}; - bigint C {std::string(kNines)}; + bigint A{std::string(kHugeA)}; + bigint B{std::string(kHugeB)}; + bigint C{std::string(kNines)}; }; class BigInt_AddParamTest : public ::testing::TestWithParam{}; class BigInt_SubParamTest : public ::testing::TestWithParam{}; @@ -86,31 +97,29 @@ class BigInt_MulParamTest : public ::testing::TestWithParam{}; class BigInt_DivParamTest : public ::testing::TestWithParam{}; class BigInt_ModParamTest : public ::testing::TestWithParam{}; -TEST(Test_BigInt, Invalid_Tests) -{ - EXPECT_THROW(bigint('a'),std::runtime_error); - EXPECT_THROW(bigint(static_cast(0)),std::runtime_error); - EXPECT_THROW(bigint(static_cast(-1)),std::runtime_error); - EXPECT_THROW(bigint("a"),std::runtime_error); - EXPECT_THROW(bigint("?"),std::runtime_error); - EXPECT_THROW(bigint(""),std::runtime_error); - EXPECT_THROW(bigint("123456a7"),std::runtime_error); - EXPECT_THROW(bigint("-123456a7"),std::runtime_error); - EXPECT_THROW(bigint("01234567"),std::runtime_error); - EXPECT_THROW(bigint("007"),std::runtime_error); - ASSERT_THROW(bigint("1234567.9"),std::runtime_error); - ASSERT_THROW(bigint("+1234567"),std::runtime_error); - ASSERT_THROW(bigint(" 1234567"),std::runtime_error); - ASSERT_THROW(bigint("1234567 "),std::runtime_error); - EXPECT_THROW(bigint("-0"),std::runtime_error); - EXPECT_THROW(bigint("-"),std::runtime_error); - EXPECT_THROW(bigint("-00"),std::runtime_error); - EXPECT_THROW(bigint("00"),std::runtime_error); - EXPECT_THROW(bigint("0.0"),std::runtime_error); +TEST(Test_BigInt, Invalid_Tests) { + EXPECT_THROW(bigint('a'), std::runtime_error); + EXPECT_THROW(bigint(static_cast(0)), std::runtime_error); + EXPECT_THROW(bigint(static_cast(-1)), std::runtime_error); + EXPECT_THROW(bigint("a"), std::runtime_error); + EXPECT_THROW(bigint("?"), std::runtime_error); + EXPECT_THROW(bigint(""), std::runtime_error); + EXPECT_THROW(bigint("123456a7"), std::runtime_error); + EXPECT_THROW(bigint("-123456a7"), std::runtime_error); + EXPECT_THROW(bigint("01234567"), std::runtime_error); + EXPECT_THROW(bigint("007"), std::runtime_error); + ASSERT_THROW(bigint("1234567.9"), std::runtime_error); + ASSERT_THROW(bigint("+1234567"), std::runtime_error); + ASSERT_THROW(bigint(" 1234567"), std::runtime_error); + ASSERT_THROW(bigint("1234567 "), std::runtime_error); + EXPECT_THROW(bigint("-0"), std::runtime_error); + EXPECT_THROW(bigint("-"), std::runtime_error); + EXPECT_THROW(bigint("-00"), std::runtime_error); + EXPECT_THROW(bigint("00"), std::runtime_error); + EXPECT_THROW(bigint("0.0"), std::runtime_error); } -TEST(Test_BigInt, Creation_Tests) -{ +TEST(Test_BigInt, Creation_Tests) { int my_int = 100; long my_long = 100; long long my_longlong = 100; @@ -146,8 +155,46 @@ TEST(Test_BigInt, Creation_Tests) EXPECT_EQ(bigint(my_string4), "-9223372036854775809"); } -TEST(Test_BigInt, Stream_Tests) -{ +TEST(Test_BigInt, Unary_Tests) { + bigint A{std::string(kHugeA)}; + bigint B{std::string(kHugeA)}; + + A++; + EXPECT_EQ(A, B + 1); + A--; + EXPECT_EQ(A, B); + EXPECT_EQ(++A, B + 1); + EXPECT_EQ(--A, B); +} + +TEST(Test_BigInt, Hash_Tests) { + const std::hash hasher; + bigint A{std::string(kHugeA)}; + bigint B{std::string(kHugeB)}; + + EXPECT_EQ(hasher(bigint(0)), hasher(bigint(0))); + EXPECT_EQ(hasher(bigint(1)), hasher(bigint(1))); + EXPECT_EQ(hasher(bigint(-1)), hasher(bigint(-1))); + EXPECT_EQ(hasher(A), hasher(A)); + + EXPECT_NE(hasher(bigint(0)), hasher(bigint(1))); + EXPECT_NE(hasher(bigint(-1)), hasher(bigint(1))); + EXPECT_NE(hasher(A), hasher(A + 1)); + + std::unordered_set set; + + set.insert(A); + set.insert(B); + EXPECT_EQ(set.size(), 2); + EXPECT_EQ(set.count(A), 1); + EXPECT_EQ(set.count(B), 1); + + EXPECT_EQ(set.find(A), set.find(A)); + set.insert(A); + EXPECT_EQ(set.count(A), 1); +} + +TEST(Test_BigInt, Stream_Tests) { std::stringstream my_stream; my_stream << bigint(55); EXPECT_EQ(my_stream.str(), "55"); @@ -162,8 +209,7 @@ TEST(Test_BigInt, Stream_Tests) EXPECT_EQ(my_stream.str(), std::string{kHugeA}); } -TEST(Test_BigInt, Bool_Tests) -{ +TEST(Test_BigInt, Bool_Tests) { EXPECT_EQ(static_cast(bigint(1)), true); EXPECT_EQ(static_cast(bigint(0)), false); EXPECT_EQ(static_cast(bigint()), false); @@ -172,17 +218,15 @@ TEST(Test_BigInt, Bool_Tests) EXPECT_EQ(static_cast(bigint(std::string{kHugeA})), true); } -TEST(Test_BigInt, Negate_Tests) -{ +TEST(Test_BigInt, Negate_Tests) { EXPECT_EQ(-bigint(0), 0); EXPECT_EQ(-bigint(1), -1); EXPECT_EQ(-bigint(-1), 1); EXPECT_EQ(-bigint(std::string{kHugeA}), bigint("-" + std::string{kHugeA})); } -TEST_P(BigInt_AddParamTest, Addition_Tests) -{ - const auto&[lhs, rhs, expected] = GetParam(); +TEST_P(BigInt_AddParamTest, Addition_Tests) { + const auto& [lhs, rhs, expected] = GetParam(); const bigint a{lhs}; const bigint b{rhs}; const bigint sum = a + b; @@ -190,9 +234,8 @@ TEST_P(BigInt_AddParamTest, Addition_Tests) EXPECT_EQ(sum, bigint{expected}); } -TEST_P(BigInt_SubParamTest, Subtraction_Tests) -{ - const auto&[lhs, rhs, expected] = GetParam(); +TEST_P(BigInt_SubParamTest, Subtraction_Tests) { + const auto& [lhs, rhs, expected] = GetParam(); const bigint a{lhs}; const bigint b{rhs}; const bigint sub = a - b; @@ -200,9 +243,8 @@ TEST_P(BigInt_SubParamTest, Subtraction_Tests) EXPECT_EQ(sub, bigint{expected}); } -TEST_P(BigInt_MulParamTest, Multiplication_Tests) -{ - const auto&[lhs, rhs, expected] = GetParam(); +TEST_P(BigInt_MulParamTest, Multiplication_Tests) { + const auto& [lhs, rhs, expected] = GetParam(); const bigint a{lhs}; const bigint b{rhs}; const bigint mul = a * b; @@ -210,9 +252,8 @@ TEST_P(BigInt_MulParamTest, Multiplication_Tests) EXPECT_EQ(mul, bigint{expected}); } -TEST_P(BigInt_DivParamTest, Division_Tests) -{ - const auto&[lhs, rhs, expected] = GetParam(); +TEST_P(BigInt_DivParamTest, Division_Tests) { + const auto& [lhs, rhs, expected] = GetParam(); const bigint a{lhs}; const bigint b{rhs}; const bigint div = a / b; @@ -220,9 +261,8 @@ TEST_P(BigInt_DivParamTest, Division_Tests) EXPECT_EQ(div, bigint{expected}); } -TEST_P(BigInt_ModParamTest, Modulus_Tests) -{ - const auto&[lhs, rhs, expected] = GetParam(); +TEST_P(BigInt_ModParamTest, Modulus_Tests) { + const auto& [lhs, rhs, expected] = GetParam(); const bigint a{lhs}; const bigint b{rhs}; const bigint mod = a % b; @@ -231,112 +271,108 @@ TEST_P(BigInt_ModParamTest, Modulus_Tests) } INSTANTIATE_TEST_SUITE_P(SmallValueAdd, BigInt_AddParamTest, ::testing::Values( -TestCase{"0", "0", "0"}, -TestCase{"0", "5", "5"}, -TestCase{"5", "0", "5"}, -TestCase{"123", "456", "579"}, -TestCase{"999", "1", "1000"}, - -TestCase{"7", "-3", "4"}, -TestCase{"-7", "3", "-4"}, -TestCase{"-7", "-3", "-10"}, -TestCase{"-10", "10", "0"}, -TestCase{"10", "-10", "0"} -)); + TestCase{"0", "0", "0"}, + TestCase{"0", "5", "5"}, + TestCase{"5", "0", "5"}, + TestCase{"123", "456", "579"}, + TestCase{"999", "1", "1000"}, + + TestCase{"7", "-3", "4"}, + TestCase{"-7", "3", "-4"}, + TestCase{"-7", "-3", "-10"}, + TestCase{"-10", "10", "0"}, + TestCase{"10", "-10", "0"} + )); INSTANTIATE_TEST_SUITE_P(SmallValueSub, BigInt_SubParamTest, ::testing::Values( -TestCase{"0", "0", "0"}, -TestCase{"0", "5", "-5"}, -TestCase{"5", "0", "5"}, -TestCase{"999", "1", "998"}, -TestCase{"1000", "1", "999"}, - -TestCase{"7", "-3", "10"}, -TestCase{"-7", "3", "-10"}, -TestCase{"-7", "-3", "-4"}, -TestCase{"-10", "10", "-20"}, -TestCase{"10", "-10", "20"}, -TestCase{"-10", "-10", "0"} -)); + TestCase{"0", "0", "0"}, + TestCase{"0", "5", "-5"}, + TestCase{"5", "0", "5"}, + TestCase{"999", "1", "998"}, + TestCase{"1000", "1", "999"}, + + TestCase{"7", "-3", "10"}, + TestCase{"-7", "3", "-10"}, + TestCase{"-7", "-3", "-4"}, + TestCase{"-10", "10", "-20"}, + TestCase{"10", "-10", "20"}, + TestCase{"-10", "-10", "0"} + )); INSTANTIATE_TEST_SUITE_P(SmallValueMul, BigInt_MulParamTest, ::testing::Values( -TestCase{"0", "0", "0"}, -TestCase{"0", "5", "0"}, -TestCase{"5", "0", "0"}, -TestCase{"999", "1", "999"}, + TestCase{"0", "0", "0"}, + TestCase{"0", "5", "0"}, + TestCase{"5", "0", "0"}, + TestCase{"999", "1", "999"}, -TestCase{"7", "-3", "-21"}, -TestCase{"-7", "3", "-21"}, -TestCase{"-7", "-3", "21"} -)); + TestCase{"7", "-3", "-21"}, + TestCase{"-7", "3", "-21"}, + TestCase{"-7", "-3", "21"} + )); INSTANTIATE_TEST_SUITE_P(SmallValueDiv, BigInt_DivParamTest, ::testing::Values( -TestCase{"0", "5", "0"}, -TestCase{"999", "1", "999"}, + TestCase{"0", "5", "0"}, + TestCase{"999", "1", "999"}, -TestCase{"7", "-3", "-2"}, -TestCase{"-7", "3", "-2"}, -TestCase{"-7", "-3", "2"} -)); + TestCase{"7", "-3", "-2"}, + TestCase{"-7", "3", "-2"}, + TestCase{"-7", "-3", "2"} + )); INSTANTIATE_TEST_SUITE_P(LargeValuesAdd, BigInt_AddParamTest, ::testing::Values( -TestCase{kHugeA, kHugeB, AplusB}, -TestCase{kHugeB, kHugeA, AplusB}, -TestCase{kHugeA, "0", kHugeA} -)); + TestCase{kHugeA, kHugeB, AplusB}, + TestCase{kHugeB, kHugeA, AplusB}, + TestCase{kHugeA, "0", kHugeA} + )); INSTANTIATE_TEST_SUITE_P(LargeValueSub, BigInt_SubParamTest, ::testing::Values( -TestCase{kHugeA, kHugeB, AminusB}, -TestCase{kHugeB, kHugeA, BminusA}, -TestCase{kHugeA, kHugeA, "0"}, -TestCase{kHugeA, "0", kHugeA}, -TestCase{"0", kHugeA, "-" + std::string{kHugeA}}, -TestCase{kNines, "9900000000000000000", "99999999999999999"} -)); + TestCase{kHugeA, kHugeB, AminusB}, + TestCase{kHugeB, kHugeA, BminusA}, + TestCase{kHugeA, kHugeA, "0"}, + TestCase{kHugeA, "0", kHugeA}, + TestCase{"0", kHugeA, "-" + std::string{kHugeA}}, + TestCase{kNines, "9900000000000000000", "99999999999999999"} + )); INSTANTIATE_TEST_SUITE_P(LargeValueMul, BigInt_MulParamTest, ::testing::Values( -TestCase{kHugeA, kHugeB, AmulB}, -TestCase{kHugeB, kHugeA, AmulB} -)); + TestCase{kHugeA, kHugeB, AmulB}, + TestCase{kHugeB, kHugeA, AmulB} + )); INSTANTIATE_TEST_SUITE_P(LargeValueDiv, BigInt_DivParamTest, ::testing::Values( -TestCase{kHugeA, kHugeB, AdivB}, -TestCase{kHugeA, kHugeA, "1"}, -TestCase{"0", kHugeA, "0"}, -TestCase{kHugeA, "-" + std::string{kHugeB}, "-" + std::string{AdivB}}, -TestCase{kHugeB, kHugeA, "0"} -)); + TestCase{kHugeA, kHugeB, AdivB}, + TestCase{kHugeA, kHugeA, "1"}, + TestCase{"0", kHugeA, "0"}, + TestCase{kHugeA, "-" + std::string{kHugeB}, "-" + std::string{AdivB}}, + TestCase{kHugeB, kHugeA, "0"} + )); INSTANTIATE_TEST_SUITE_P(LargeValueMod, BigInt_ModParamTest, ::testing::Values( -TestCase{kHugeA, kHugeB, AmodB}, -TestCase{kHugeB, kHugeA, kHugeB}, -TestCase{kHugeA, kHugeA, "0"}, -TestCase{kHugeA, "1", "0"} -)); + TestCase{kHugeA, kHugeB, AmodB}, + TestCase{kHugeB, kHugeA, kHugeB}, + TestCase{kHugeA, kHugeA, "0"}, + TestCase{kHugeA, "1", "0"} + )); -TEST_F(Test_BigInt_F, Commutivity_Tests) -{ +TEST_F(Test_BigInt_F, Commutivity_Tests) { EXPECT_EQ(A + B, B + A); EXPECT_EQ((A + B) + C, A + (B + C)); EXPECT_EQ(A * B, B * A); EXPECT_EQ((A * B) * C, A * (B * C)); } -TEST_F(Test_BigInt_F, Distributivity_Tests) -{ +TEST_F(Test_BigInt_F, Distributivity_Tests) { EXPECT_EQ(A * (B + C), (A * B) + (A * C)); } -TEST(Test_BigInt, Domain_Tests) -{ +TEST(Test_BigInt, Domain_Tests) { EXPECT_THROW(bigint{0} / 0, std::domain_error); EXPECT_THROW(bigint{77} / 0, std::domain_error); EXPECT_THROW(bigint{std::string{kHugeA}} / 0, std::domain_error); EXPECT_THROW(bigint{77} % 0, std::domain_error); } -TEST(Test_BigInt, Comparison_Tests) -{ +TEST(Test_BigInt, Comparison_Tests) { bigint small_number = 9955; bigint huge_number1{std::string{kHugeA}}; bigint huge_number2{std::string{kHugeB}}; @@ -379,11 +415,9 @@ TEST(Test_BigInt, Comparison_Tests) EXPECT_FALSE(123456789 >= huge_number1); } -TEST_F(Test_BigInt_Performance, Addition_Speed_Tests) -{ +TEST_F(Test_BigInt_Performance, Addition_Speed_Tests) { std::cout << "--- Starting Performance Tests (Sample size: " << number_count << ") ---" << std::endl; for (const size_t number_size : sizes) { - std::vector huge_numbers; huge_numbers.reserve(number_count); for (int i = 0; i < number_count; ++i) { @@ -405,11 +439,10 @@ TEST_F(Test_BigInt_Performance, Addition_Speed_Tests) std::cout << std::endl; } } -TEST_F(Test_BigInt_Performance, Subtraction_Speed_Tests) -{ + +TEST_F(Test_BigInt_Performance, Subtraction_Speed_Tests) { std::cout << "--- Starting Performance Tests (Sample size: " << number_count << ") ---" << std::endl; for (const size_t number_size : sizes) { - std::vector huge_numbers; huge_numbers.reserve(number_count); for (int i = 0; i < number_count; ++i) { @@ -420,7 +453,7 @@ TEST_F(Test_BigInt_Performance, Subtraction_Speed_Tests) bigint answer = 0; - measure_execution(number_count,"Subtraction", number_size, [&]() { + measure_execution(number_count, "Subtraction", number_size, [&]() { for (size_t i = 0; i < huge_numbers.size() - 1; ++i) { answer = huge_numbers[i] - huge_numbers[i + 1]; // Tiny check to force evaluation @@ -432,11 +465,9 @@ TEST_F(Test_BigInt_Performance, Subtraction_Speed_Tests) } } -TEST_F(Test_BigInt_Performance, Multiplication_Speed_Tests) -{ +TEST_F(Test_BigInt_Performance, Multiplication_Speed_Tests) { std::cout << "--- Starting Performance Tests (Sample size: " << number_count << ") ---" << std::endl; for (const size_t number_size : sizes) { - std::vector huge_numbers; huge_numbers.reserve(number_count); for (int i = 0; i < number_count; ++i) { @@ -447,7 +478,7 @@ TEST_F(Test_BigInt_Performance, Multiplication_Speed_Tests) bigint answer = 0; - measure_execution(number_count,"Multiplication", number_size, [&]() { + measure_execution(number_count, "Multiplication", number_size, [&]() { for (size_t i = 0; i < huge_numbers.size() - 1; ++i) { answer = huge_numbers[i] * huge_numbers[i + 1]; // Tiny check to force evaluation @@ -459,11 +490,9 @@ TEST_F(Test_BigInt_Performance, Multiplication_Speed_Tests) } } -TEST_F(Test_BigInt_Performance, Division_Speed_Tests) -{ +TEST_F(Test_BigInt_Performance, Division_Speed_Tests) { std::cout << "--- Starting Performance Tests (Sample size: " << number_count << ") ---" << std::endl; for (const size_t number_size : sizes) { - std::vector huge_numbers; huge_numbers.reserve(number_count); for (int i = 0; i < number_count; ++i) {