abacus: bignum: add log2
This commit is contained in:
parent
4b85d22923
commit
c730705a13
|
@ -468,4 +468,28 @@ BigNum sqrt(BigNum const& num) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BigNum log2(BigNum const& num) {
|
||||||
|
assert(num.is_canonicalized());
|
||||||
|
|
||||||
|
if (num.is_zero()) {
|
||||||
|
throw std::invalid_argument("attempt to take the log2 of zero");
|
||||||
|
} else if (num.is_negative()) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"attempt to take the log2 of a negative number");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tmp = num;
|
||||||
|
auto res = BigNum(0);
|
||||||
|
auto one = BigNum(1);
|
||||||
|
|
||||||
|
while (tmp > one) {
|
||||||
|
tmp.digits_ = do_halve(tmp.digits_);
|
||||||
|
res += one;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(res.is_canonicalized());
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace abacus::bignum
|
} // namespace abacus::bignum
|
||||||
|
|
|
@ -91,6 +91,8 @@ public:
|
||||||
|
|
||||||
friend BigNum sqrt(BigNum const& num);
|
friend BigNum sqrt(BigNum const& num);
|
||||||
|
|
||||||
|
friend BigNum log2(BigNum const& num);
|
||||||
|
|
||||||
friend bool operator==(BigNum const& lhs, BigNum const& rhs) {
|
friend bool operator==(BigNum const& lhs, BigNum const& rhs) {
|
||||||
return lhs.equal(rhs);
|
return lhs.equal(rhs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,3 +376,24 @@ TEST(BigNum, sqrt) {
|
||||||
EXPECT_EQ(sqrt(ninety_nine), nine);
|
EXPECT_EQ(sqrt(ninety_nine), nine);
|
||||||
EXPECT_EQ(sqrt(hundred), ten);
|
EXPECT_EQ(sqrt(hundred), ten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(BigNum, log2) {
|
||||||
|
auto const zero = BigNum(0);
|
||||||
|
auto const one = BigNum(1);
|
||||||
|
auto const two = BigNum(2);
|
||||||
|
auto const three = BigNum(3);
|
||||||
|
auto const four = BigNum(4);
|
||||||
|
auto const five = BigNum(5);
|
||||||
|
auto const seven = BigNum(7);
|
||||||
|
auto const eight = BigNum(8);
|
||||||
|
auto const nine = BigNum(9);
|
||||||
|
|
||||||
|
EXPECT_EQ(log2(one), zero);
|
||||||
|
EXPECT_EQ(log2(two), one);
|
||||||
|
EXPECT_EQ(log2(three), one);
|
||||||
|
EXPECT_EQ(log2(four), two);
|
||||||
|
EXPECT_EQ(log2(five), two);
|
||||||
|
EXPECT_EQ(log2(seven), two);
|
||||||
|
EXPECT_EQ(log2(eight), three);
|
||||||
|
EXPECT_EQ(log2(nine), three);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue