From 0651e4598bde59ab41d9e58cd905acf2f50c1219 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 23 Sep 2020 16:04:40 -0700 Subject: [PATCH] Minor tweaks to get_cached_power --- include/fmt/format-inl.h | 61 ++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index e3817886b914..ee5ac889833d 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -1934,6 +1934,7 @@ template struct cache_accessor; template <> struct cache_accessor { using carrier_uint = float_info::carrier_uint; using cache_entry_type = uint64_t; + static uint64_t get_cached_power(int k) FMT_NOEXCEPT { FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, "k is out of range"); @@ -1986,6 +1987,7 @@ template <> struct cache_accessor { template <> struct cache_accessor { using carrier_uint = float_info::carrier_uint; using cache_entry_type = uint128_wrapper; + static uint128_wrapper get_cached_power(int k) FMT_NOEXCEPT { FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, "k is out of range"); @@ -1996,53 +1998,46 @@ template <> struct cache_accessor { #else static const int compression_ratio = 27; - // Compute base index + // Compute base index. int cache_index = (k - float_info::min_k) / compression_ratio; int kb = cache_index * compression_ratio + float_info::min_k; int offset = k - kb; - // Get base cache + // Get base cache. uint128_wrapper base_cache = data::dragonbox_pow10_significands_128[cache_index]; + if (offset == 0) return base_cache; - if (offset == 0) { - return base_cache; - } else { - // Compute the required amount of bit-shift - int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset; - FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected"); - - // Try to recover the real cache - uint64_t pow5 = data::powers_of_5_64[offset]; - uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5); - uint128_wrapper middle_low = - umul128(base_cache.low() - (kb < 0 ? 1 : 0), pow5); + // Compute the required amount of bit-shift. + int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset; + FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected"); - recovered_cache += middle_low.high(); + // Try to recover the real cache. + uint64_t pow5 = data::powers_of_5_64[offset]; + uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5); + uint128_wrapper middle_low = + umul128(base_cache.low() - (kb < 0 ? 1 : 0), pow5); - uint64_t high_to_middle = recovered_cache.high() << (64 - alpha); - uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); + recovered_cache += middle_low.high(); - recovered_cache = - uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle, - ((middle_low.low() >> alpha) | middle_to_low)}; + uint64_t high_to_middle = recovered_cache.high() << (64 - alpha); + uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); - if (kb < 0) { - recovered_cache += 1; - } + recovered_cache = + uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle, + ((middle_low.low() >> alpha) | middle_to_low)}; - // Get error - int error_idx = (k - float_info::min_k) / 16; - uint32_t error = (data::dragonbox_pow10_recovery_errors[error_idx] >> - ((k - float_info::min_k) % 16) * 2) & - 0x3; + if (kb < 0) recovered_cache += 1; - // Add the error back - FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), ""); - recovered_cache = {recovered_cache.high(), recovered_cache.low() + error}; + // Get error. + int error_idx = (k - float_info::min_k) / 16; + uint32_t error = (data::dragonbox_pow10_recovery_errors[error_idx] >> + ((k - float_info::min_k) % 16) * 2) & + 0x3; - return recovered_cache; - } + // Add the error back. + FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), ""); + return {recovered_cache.high(), recovered_cache.low() + error}; #endif }