diff --git a/bigint.h b/bigint.h index 936be5f..cf1a5d3 100644 --- a/bigint.h +++ b/bigint.h @@ -284,6 +284,7 @@ namespace BigInt { friend std::hash; static bigint pow(const bigint& base, const bigint& exponent) { + if (exponent < 0) return 0; if (exponent == 0) return 1; if (exponent == 1) return base; @@ -643,28 +644,22 @@ namespace BigInt { bigint remainder = numerator; bigint quotient = 0; - auto count = count_digits(remainder) - count_digits(denominator) - 1; + while (remainder >= denominator) { + int count = count_digits(remainder) - count_digits(denominator) - 1; - auto numerator_size = pow(10, count); - - auto temp = denominator * numerator_size; - - while (denominator * numerator_size < remainder) { - temp = denominator * numerator_size; - remainder -= temp; - quotient += numerator_size; - count = count_digits(remainder) - count_digits(denominator) - 1; + // Prevent negative exponents which cause pow() to return 0 + if (count < 0) { + count = 0; + } + bigint numerator_size = pow(10, count); + bigint temp = denominator * numerator_size; - if (numerator_size <= 1) { - quotient += remainder / denominator; - break; - } - if (remainder.vec.size() <= 1) { - quotient += remainder.vec.back() / denominator.vec.back(); - break; + // Repeatedly subtract the chunk from the remainder + while (remainder >= temp) { + remainder -= temp; + quotient += numerator_size; } - numerator_size = pow(10, count); } return quotient; diff --git a/tests/test.cpp b/tests/test.cpp index 1b660fc..3852935 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -74,8 +74,8 @@ static auto measure_execution = [](const int count, const char* label, const siz class Test_BigInt_Performance : public ::testing::Test { protected: - static constexpr size_t number_count = 2; - const std::vector sizes = {10, 100, 1000, 10000, 50000}; + static constexpr size_t number_count = 50; + const std::vector sizes = {10, 100, 1000, 10000}; volatile int dce_sink = 0; void SetUp() override { @@ -356,7 +356,8 @@ INSTANTIATE_TEST_SUITE_P(LargeValueDiv, BigInt_DivParamTest, ::testing::Values( TestCase{kHugeA, kHugeA, "1"}, TestCase{"0", kHugeA, "0"}, TestCase{kHugeA, "-" + std::string{kHugeB}, "-" + std::string{AdivB}}, - TestCase{kHugeB, kHugeA, "0"} + TestCase{kHugeB, kHugeA, "0"}, + TestCase{"12345678901234567890", "4117416960", "2998403858"} )); INSTANTIATE_TEST_SUITE_P(LargeValueMod, BigInt_ModParamTest, ::testing::Values(