diff --git a/source/math/big_integer b/source/math/big_integer index 073b514..8629dd9 100644 --- a/source/math/big_integer +++ b/source/math/big_integer @@ -739,20 +739,23 @@ namespace gtl { } public: - /// @brief Get the length of the big number in allocated bits for the magnitude. + /// @brief Get the length of the big number in allocated bits. /// @return The number of bits allocated to store the big number. + /// @note This does not include a bit to store the sign. unsigned long long int get_length_bits() const { return this->magnitude.get_length_bits(); } - /// @brief Get the length of the big number in allocated bytes for the magnitude. - /// @return The number of bytes allocated to store the big number. + /// @brief Get the length of the big number in bytes. + /// @return The number of bytes needed to store the big number. + /// @note This does not include a byte to store the sign. unsigned long long int get_length_bytes() const { return this->magnitude.get_length_bytes(); } /// @brief Get the length of the big number as a decimal number. /// @return The number of digits required to represent the big number. + /// @note This does not include a character to store the sign. unsigned long long int get_length_decimal() const { return this->magnitude.get_length_decimal(); } diff --git a/source/math/big_unsigned b/source/math/big_unsigned index a11e804..2f6698f 100644 --- a/source/math/big_unsigned +++ b/source/math/big_unsigned @@ -903,14 +903,24 @@ namespace gtl { } public: - /// @brief Get the length of the big number in allocated bits, this will be a multiple of eight. + /// @brief Get the length of the big number in allocated bits. /// @return The number of bits allocated to store the big number. unsigned long long int get_length_bits() const { - return this->chunks.size() * big_unsigned::chunk_bits; + unsigned int msb = this->chunks.back() | 1; + unsigned int remainder = big_unsigned::chunk_bits; + while (msb < 0x01000000) { + msb <<= 8; + remainder -= 8; + } + while ((msb > 0) && (!(msb & 0x80000000))) { + msb <<= 1; + --remainder; + } + return remainder + (this->chunks.size() - 1) * big_unsigned::chunk_bits; } - /// @brief Get the length of the big number in allocated bytes. - /// @return The number of bytes allocated to store the big number. + /// @brief Get the length of the big number in bytes. + /// @return The number of bytes needed to store the big number. unsigned long long int get_length_bytes() const { const unsigned long long int remainder = (this->chunks.back() > 0xFFFFFF) + (this->chunks.back() > 0xFFFF) + (this->chunks.back() > 0xFF) + 1; return remainder + (this->chunks.size() - 1) * sizeof(chunk_type); diff --git a/tests/math/big_integer.test.cpp b/tests/math/big_integer.test.cpp index 048ac51..51d1e54 100644 --- a/tests/math/big_integer.test.cpp +++ b/tests/math/big_integer.test.cpp @@ -1156,24 +1156,24 @@ TEST(big_integer, operator, get_length_bits) { gtl::big_integer big_integer_lhs(lhs); gtl::big_integer big_integer_rhs(rhs); - REQUIRE(big_integer_lhs.get_length_bits() == 64); - REQUIRE(big_integer_rhs.get_length_bits() == 32); + REQUIRE(big_integer_lhs.get_length_bits() == 63); + REQUIRE(big_integer_rhs.get_length_bits() == 2); constexpr static const char* two_power_333 = "17498005798264095394980017816940970922825355447145699491406164851279623993595007385788105416184430592"; gtl::big_integer big_integer_333(two_power_333, testbench::string_length(two_power_333)); - REQUIRE(big_integer_333.get_length_bits() == 352); + REQUIRE(big_integer_333.get_length_bits() == 334); signed long long int lhs_negative = -(1ll << 62); signed long long int rhs_negative = -2; gtl::big_integer big_integer_lhs_negative(lhs_negative); gtl::big_integer big_integer_rhs_negative(rhs_negative); - REQUIRE(big_integer_lhs_negative.get_length_bits() == 64); - REQUIRE(big_integer_rhs_negative.get_length_bits() == 32); + REQUIRE(big_integer_lhs_negative.get_length_bits() == 63); + REQUIRE(big_integer_rhs_negative.get_length_bits() == 2); constexpr static const char* two_power_333_negative = "-17498005798264095394980017816940970922825355447145699491406164851279623993595007385788105416184430592"; gtl::big_integer big_integer_333_negative(two_power_333_negative, testbench::string_length(two_power_333_negative)); - REQUIRE(big_integer_333_negative.get_length_bits() == 352); + REQUIRE(big_integer_333_negative.get_length_bits() == 334); } TEST(big_integer, operator, get_length_bytes) { diff --git a/tests/math/big_unsigned.test.cpp b/tests/math/big_unsigned.test.cpp index 8eac4b6..3922644 100644 --- a/tests/math/big_unsigned.test.cpp +++ b/tests/math/big_unsigned.test.cpp @@ -652,12 +652,12 @@ TEST(big_unsigned, operator, get_length_bits) { gtl::big_unsigned big_unsigned_lhs(lhs); gtl::big_unsigned big_unsigned_rhs(rhs); - REQUIRE(big_unsigned_lhs.get_length_bits() == 64); - REQUIRE(big_unsigned_rhs.get_length_bits() == 32); + REQUIRE(big_unsigned_lhs.get_length_bits() == 63); + REQUIRE(big_unsigned_rhs.get_length_bits() == 2); constexpr static const char* two_power_333 = "17498005798264095394980017816940970922825355447145699491406164851279623993595007385788105416184430592"; gtl::big_unsigned big_unsigned_333(two_power_333, testbench::string_length(two_power_333)); - REQUIRE(big_unsigned_333.get_length_bits() == 352); + REQUIRE(big_unsigned_333.get_length_bits() == 334); } TEST(big_unsigned, operator, get_length_bytes) {