diff --git a/include/fast_float/decimal_to_binary.h b/include/fast_float/decimal_to_binary.h index 0a4296f..687b834 100644 --- a/include/fast_float/decimal_to_binary.h +++ b/include/fast_float/decimal_to_binary.h @@ -20,18 +20,18 @@ namespace fast_float { template fastfloat_really_inline value128 compute_product_approximation(int64_t q, uint64_t w) { - const int index = 2 * int(q - smallest_power_of_five); + const int index = 2 * int(q - powers::smallest_power_of_five); // For small values of q, e.g., q in [0,27], the answer is always exact because // The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]); // gives the exact answer. - value128 firstproduct = full_multiplication(w, power_of_five_128[index]); + value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]); static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]"); constexpr uint64_t precision_mask = (bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision) : uint64_t(0xFFFFFFFFFFFFFFFF); if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower) // regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed. - value128 secondproduct = full_multiplication(w, power_of_five_128[index + 1]); + value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]); firstproduct.low += secondproduct.high; if(secondproduct.high > firstproduct.low) { firstproduct.high++; @@ -83,7 +83,7 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept { answer.mantissa = 0; return answer; } - // At this point in time q is in [smallest_power_of_five, largest_power_of_five]. + // At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five]. // We want the most significant bit of i to be 1. Shift if needed. int lz = leading_zeroes(w); diff --git a/include/fast_float/fast_table.h b/include/fast_float/fast_table.h index b68fcac..ec05e8b 100644 --- a/include/fast_float/fast_table.h +++ b/include/fast_float/fast_table.h @@ -28,10 +28,14 @@ namespace fast_float { * infinite in binary64 so we never need to worry about powers * of 5 greater than 308. */ -constexpr int smallest_power_of_five = -342; -constexpr int largest_power_of_five = 308; +template +struct powers_template { + +constexpr static int smallest_power_of_five = binary_format::smallest_power_of_ten(); +constexpr static int largest_power_of_five = binary_format::largest_power_of_ten(); +constexpr static int number_of_entries = 2 * (largest_power_of_five - smallest_power_of_five + 1); // Powers of five from 5^-342 all the way to 5^308 rounded toward one. -const uint64_t power_of_five_128[]= { +constexpr static uint64_t power_of_five_128[number_of_entries] = { 0xeef453d6923bd65a,0x113faa2906a13b3f, 0x9558b4661b6565f8,0x4ac7ca59a424c507, 0xbaaee17fa23ebf76,0x5d79bcf00d2df649, @@ -683,6 +687,8 @@ const uint64_t power_of_five_128[]= { 0xb6472e511c81471d,0xe0133fe4adf8e952, 0xe3d8f9e563a198e5,0x58180fddd97723a6, 0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,}; +}; +using powers = powers_template<>; }