diff --git a/base/base_tests/bits_test.cpp b/base/base_tests/bits_test.cpp index b7a4f415cd..79cac2c797 100644 --- a/base/base_tests/bits_test.cpp +++ b/base/base_tests/bits_test.cpp @@ -85,3 +85,18 @@ UNIT_TEST(ZigZagDecode) TEST_EQUAL(bits::ZigZagDecode(256U), 128, ()); } +UNIT_TEST(NumHiZeroBits32) +{ + TEST_EQUAL(bits::NumHiZeroBits32(0), 32, ()); + TEST_EQUAL(bits::NumHiZeroBits32(0xFFFFFFFF), 0, ()); + TEST_EQUAL(bits::NumHiZeroBits32(0x0FABCDEF), 4, ()); + TEST_EQUAL(bits::NumHiZeroBits32(0x000000FF), 24, ()); +} + +UNIT_TEST(NumHiZeroBits64) +{ + TEST_EQUAL(bits::NumHiZeroBits64(0), 64, ()); + TEST_EQUAL(bits::NumHiZeroBits64(0xFFFFFFFFFFFFFFFFULL), 0, ()); + TEST_EQUAL(bits::NumHiZeroBits64(0x0FABCDEF0FABCDEFULL), 4, ()); + TEST_EQUAL(bits::NumHiZeroBits64(0x000000000000FDEFULL), 48, ()); +} diff --git a/base/bits.hpp b/base/bits.hpp index f0e5c13345..111c1c36e0 100644 --- a/base/bits.hpp +++ b/base/bits.hpp @@ -4,6 +4,7 @@ #include "assert.hpp" #include "../std/type_traits.hpp" +#include "../std/stdint.hpp" namespace bits @@ -146,4 +147,21 @@ namespace bits uint8_t * pData = static_cast(p); pData[offset >> 3] |= (1 << (offset & 7)); } + + // Compute number of zero bits from the most significant bits side. + inline uint32_t NumHiZeroBits32(uint32_t n) + { + if (n == 0) return 32; + uint32_t result = 0; + while ((n & (uint32_t(1) << 31)) == 0) { ++result; n <<= 1; } + return result; + } + + inline uint32_t NumHiZeroBits64(uint64_t n) + { + if (n == 0) return 64; + uint32_t result = 0; + while ((n & (uint64_t(1) << 63)) == 0) { ++result; n <<= 1; } + return result; + } } diff --git a/coding/arithmetic_codec.cpp b/coding/arithmetic_codec.cpp index 7a3740d755..0e5a18a392 100644 --- a/coding/arithmetic_codec.cpp +++ b/coding/arithmetic_codec.cpp @@ -4,15 +4,7 @@ #include "reader.hpp" #include "../base/assert.hpp" - -namespace { - inline u32 NumHiZeroBits32(u32 n) - { - u32 result = 0; - while ((n & (u32(1) << 31)) == 0) { ++result; n <<= 1; } - return result; - } -} +#include "../base/bits.hpp" vector FreqsToDistrTable(vector const & origFreqs) { @@ -87,7 +79,7 @@ vector ArithmeticEncoder::Finalize() } else { - u32 resultHiBits = NumHiZeroBits32(m_begin ^ last) + 1; + u32 resultHiBits = bits::NumHiZeroBits32(m_begin ^ last) + 1; u32 value = last & (~u32(0) << (32 - resultHiBits)); while (value != 0) {