Remove get_cached_power

This commit is contained in:
Victor Zverovich 2023-05-27 08:45:27 -07:00
parent 171a020c82
commit 0b8404918e
2 changed files with 4 additions and 67 deletions

View File

@ -1734,6 +1734,7 @@ FMT_CONSTEXPR inline fp operator*(fp x, fp y) {
}
template <typename T = void> struct basic_data {
// DEPRECATED!
// Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
// These are generated by support/compute-powers.py.
static constexpr uint64_t pow10_significands[87] = {
@ -1772,6 +1773,7 @@ template <typename T = void> struct basic_data {
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wnarrowing"
#endif
// DEPRECATED!
// Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
// to significands above.
static constexpr int16_t pow10_exponents[87] = {
@ -1817,37 +1819,9 @@ constexpr uint32_t basic_data<T>::fractional_part_rounding_thresholds[];
// This is a struct rather than an alias to avoid shadowing warnings in gcc.
struct data : basic_data<> {};
// DEPRECATED!
// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
FMT_CONSTEXPR inline fp get_cached_power(int min_exponent,
int& pow10_exponent) {
const int shift = 32;
// log10(2) = 0x0.4d104d427de7fbcc...
const int64_t significand = 0x4d104d427de7fbcc;
int index = static_cast<int>(
((min_exponent + fp::num_significand_bits - 1) * (significand >> shift) +
((int64_t(1) << shift) - 1)) // ceil
>> 32 // arithmetic shift
);
// Decimal exponent of the first (smallest) cached power of 10.
const int first_dec_exp = -348;
// Difference between 2 consecutive decimal exponents in cached powers of 10.
const int dec_exp_step = 8;
index = (index - first_dec_exp - 1) / dec_exp_step + 1;
pow10_exponent = first_dec_exp + index * dec_exp_step;
// Using *(x + index) instead of x[index] avoids an issue with some compilers
// using the EDG frontend (e.g. nvhpc/22.3 in C++17 mode).
return {*(data::pow10_significands + index),
*(data::pow10_exponents + index)};
}
template <typename T>
template <typename T, bool doublish = num_bits<T>() == num_bits<double>()>
using convert_float_result =
conditional_t<std::is_same<T, float>::value ||
std::numeric_limits<T>::digits ==
std::numeric_limits<double>::digits,
double, T>;
conditional_t<std::is_same<T, float>::value || doublish, double, T>;
template <typename T>
constexpr auto convert_float(T value) -> convert_float_result<T> {

View File

@ -196,43 +196,6 @@ TEST(fp_test, multiply) {
EXPECT_EQ(v.e, 4 + 8 + 64);
}
TEST(fp_test, get_cached_power) {
using limits = std::numeric_limits<double>;
for (auto exp = limits::min_exponent; exp <= limits::max_exponent; ++exp) {
int dec_exp = 0;
auto power = fmt::detail::get_cached_power(exp, dec_exp);
bigint exact, cache(power.f);
if (dec_exp >= 0) {
exact.assign_pow10(dec_exp);
if (power.e <= 0)
exact <<= -power.e;
else
cache <<= power.e;
exact.align(cache);
cache.align(exact);
auto exact_str = fmt::to_string(exact);
auto cache_str = fmt::to_string(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 *= power.f + 1; // Inexact check.
exact = 1;
exact <<= -power.e;
exact.align(cache);
auto exact_str = fmt::to_string(exact);
auto cache_str = fmt::to_string(cache);
EXPECT_EQ(exact_str.size(), cache_str.size());
EXPECT_EQ(exact_str.substr(0, 16), cache_str.substr(0, 16));
}
}
}
TEST(fp_test, dragonbox_max_k) {
using fmt::detail::dragonbox::floor_log10_pow2;
using float_info = fmt::detail::dragonbox::float_info<float>;