diff --git a/storm/Big.cpp b/storm/Big.cpp index dcb2ab7..a8d7804 100644 --- a/storm/Big.cpp +++ b/storm/Big.cpp @@ -7,6 +7,23 @@ void SBigAdd(BigData* a, BigData* b, BigData* c) { Add(a->Primary(), b->Primary(), c->Primary()); } +void SBigBitLen(BigData* num, uint32_t* len) { + auto& buffer = num->Primary(); + buffer.Trim(); + + auto index = buffer.Count() - 1; + auto high = buffer[index]; + + uint32_t bitIndex; + for (bitIndex = 31; bitIndex > 0; bitIndex--) { + if (((1 << bitIndex) & high)) { + break; + } + } + + *len = (index * 32) + bitIndex + 1; +} + int32_t SBigCompare(BigData* a, BigData* b) { return Compare(a->Primary(), b->Primary()); } diff --git a/storm/Big.hpp b/storm/Big.hpp index 8b6d7a1..291eea2 100644 --- a/storm/Big.hpp +++ b/storm/Big.hpp @@ -6,6 +6,8 @@ void SBigAdd(BigData* a, BigData* b, BigData* c); +void SBigBitLen(BigData* num, uint32_t* len); + int32_t SBigCompare(BigData* a, BigData* b); void SBigDel(BigData* num); diff --git a/test/Big.cpp b/test/Big.cpp index 7acf347..f9f16b8 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -459,6 +459,74 @@ TEST_CASE("SBigAdd", "[big]") { } } +TEST_CASE("SBigBitLen", "[big]") { + SECTION("returns bit length of 1") { + BigData* num; + SBigNew(&num); + SBigFromUnsigned(num, 1); + + uint32_t len; + SBigBitLen(num, &len); + + CHECK(len == 1); + + SBigDel(num); + } + + SECTION("returns bit length of 5") { + BigData* num; + SBigNew(&num); + SBigFromUnsigned(num, 5); + + uint32_t len; + SBigBitLen(num, &len); + + CHECK(len == 3); + + SBigDel(num); + } + + SECTION("returns bit length of 0xFFFF") { + BigData* num; + SBigNew(&num); + SBigFromUnsigned(num, 0xFFFF); + + uint32_t len; + SBigBitLen(num, &len); + + CHECK(len == 16); + + SBigDel(num); + } + + SECTION("returns bit length of 0xFFFFFFFF") { + BigData* num; + SBigNew(&num); + SBigFromUnsigned(num, 0xFFFFFFFF); + + uint32_t len; + SBigBitLen(num, &len); + + CHECK(len == 32); + + SBigDel(num); + } + + SECTION("returns bit length of 0x22222222AAAAAAAA") { + BigData* num; + SBigNew(&num); + uint64_t num_ = 0x22222222AAAAAAAA; + SBigFromBinary(num, reinterpret_cast(&num_), sizeof(num_)); + + uint32_t len; + SBigBitLen(num, &len); + + CHECK(len == 62); + + SBigDel(num); + } +} + TEST_CASE("SBigCompare", "[big]") { SECTION("compares 10 and 1") { BigData* a;