mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-27 04:20:06 +00:00
Make GetCachedPower test more precise
This commit is contained in:
parent
a581e9e5d8
commit
af8a180aed
@ -1262,9 +1262,8 @@ class bigint {
|
||||
FMT_ASSERT(compare(*this, other) >= 0, "");
|
||||
bigit borrow = 0;
|
||||
int i = other.exp_ - exp_;
|
||||
for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) {
|
||||
for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
|
||||
subtract_bigits(i, other.bigits_[j], borrow);
|
||||
}
|
||||
while (borrow > 0) subtract_bigits(i, 0, borrow);
|
||||
remove_leading_zeros();
|
||||
}
|
||||
@ -1436,22 +1435,26 @@ class bigint {
|
||||
exp_ *= 2;
|
||||
}
|
||||
|
||||
// If this bigint has a bigger exponent than other, adds trailing zero to make
|
||||
// exponents equal. This simplifies some operations such as subtraction.
|
||||
void align(const bigint& other) {
|
||||
int exp_difference = exp_ - other.exp_;
|
||||
if (exp_difference <= 0) return;
|
||||
int num_bigits = static_cast<int>(bigits_.size());
|
||||
bigits_.resize(to_unsigned(num_bigits + exp_difference));
|
||||
for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
|
||||
bigits_[j] = bigits_[i];
|
||||
std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
|
||||
exp_ -= exp_difference;
|
||||
}
|
||||
|
||||
// Divides this bignum by divisor, assigning the remainder to this and
|
||||
// returning the quotient.
|
||||
int divmod_assign(const bigint& divisor) {
|
||||
FMT_ASSERT(this != &divisor, "");
|
||||
if (compare(*this, divisor) < 0) return 0;
|
||||
int num_bigits = static_cast<int>(bigits_.size());
|
||||
FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
|
||||
int exp_difference = exp_ - divisor.exp_;
|
||||
if (exp_difference > 0) {
|
||||
// Align bigints by adding trailing zeros to simplify subtraction.
|
||||
bigits_.resize(to_unsigned(num_bigits + exp_difference));
|
||||
for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
|
||||
bigits_[j] = bigits_[i];
|
||||
std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
|
||||
exp_ -= exp_difference;
|
||||
}
|
||||
align(divisor);
|
||||
int quotient = 0;
|
||||
do {
|
||||
subtract_aligned(divisor);
|
||||
|
@ -212,14 +212,39 @@ TEST(FPTest, Multiply) {
|
||||
}
|
||||
|
||||
TEST(FPTest, GetCachedPower) {
|
||||
typedef std::numeric_limits<double> limits;
|
||||
using limits = std::numeric_limits<double>;
|
||||
for (auto exp = limits::min_exponent; exp <= limits::max_exponent; ++exp) {
|
||||
int dec_exp = 0;
|
||||
auto fp = fmt::detail::get_cached_power(exp, dec_exp);
|
||||
EXPECT_LE(exp, fp.e);
|
||||
int dec_exp_step = 8;
|
||||
EXPECT_LE(fp.e, exp + dec_exp_step * log2(10));
|
||||
EXPECT_DOUBLE_EQ(pow(10, dec_exp), ldexp(static_cast<double>(fp.f), fp.e));
|
||||
bigint exact, cache(fp.f);
|
||||
if (dec_exp >= 0) {
|
||||
exact.assign_pow10(dec_exp);
|
||||
if (fp.e <= 0)
|
||||
exact <<= -fp.e;
|
||||
else
|
||||
cache <<= fp.e;
|
||||
exact.align(cache);
|
||||
cache.align(exact);
|
||||
auto exact_str = fmt::format("{}", exact);
|
||||
auto cache_str = fmt::format("{}", cache);
|
||||
EXPECT_EQ(exact_str.size(), cache_str.size());
|
||||
EXPECT_EQ(exact_str.substr(0, 15), cache_str.substr(0, 15));
|
||||
int diff = cache_str[15] - exact_str[15];
|
||||
if (diff == 1)
|
||||
EXPECT_GT(exact_str[16], '8');
|
||||
else
|
||||
EXPECT_EQ(diff, 0);
|
||||
} else {
|
||||
cache.assign_pow10(-dec_exp);
|
||||
cache *= fp.f + 1; // Inexact check.
|
||||
exact.assign(1);
|
||||
exact <<= -fp.e;
|
||||
exact.align(cache);
|
||||
auto exact_str = fmt::format("{}", exact);
|
||||
auto cache_str = fmt::format("{}", cache);
|
||||
EXPECT_EQ(exact_str.size(), cache_str.size());
|
||||
EXPECT_EQ(exact_str.substr(0, 16), cache_str.substr(0, 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user