Minor tuning.

This commit is contained in:
Daniel Lemire 2020-10-27 19:34:21 -04:00
parent 05ad45dfb5
commit eb1103393e

View File

@ -45,7 +45,7 @@ bool is_space(uint8_t c) {
namespace { namespace {
constexpr uint32_t max_digits = 768; constexpr uint32_t max_digits = 768;
constexpr uint32_t max_digit_without_overflow = 19;
constexpr int32_t decimal_point_range = 2047; constexpr int32_t decimal_point_range = 2047;
} // namespace } // namespace
@ -140,12 +140,10 @@ struct decimal {
bool truncated; bool truncated;
uint8_t digits[max_digits]; uint8_t digits[max_digits];
// generate a mantissa by truncating to 19 digits, this assumes // Generates a mantissa by truncating to 19 digits; this function assumes
// that num_digits >= 19 (caller should check). // that num_digits >= 19 (the caller is responsible for the check).
// This function should be reasonably fast.
inline uint64_t to_truncated_mantissa() { inline uint64_t to_truncated_mantissa() {
const int64_t max_digit_with_overflow = 19;
static_assert(9999999999999999999U < 0xffffffffffffffff, "cannot fit 19 digits in an uint64_t");
static_assert(max_digit_with_overflow < max_digits, "too few max_digits");
uint64_t val; uint64_t val;
// 8 first digits // 8 first digits
::memcpy(&val, digits, sizeof(uint64_t)); ::memcpy(&val, digits, sizeof(uint64_t));
@ -158,15 +156,14 @@ struct decimal {
val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16;
uint32_t eight_digits_value = uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); uint32_t eight_digits_value = uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32);
mantissa = 100000000 * mantissa + eight_digits_value; mantissa = 100000000 * mantissa + eight_digits_value;
for(size_t i = 2*sizeof(uint64_t); i < max_digit_with_overflow; i++) { for(uint32_t i = 2*sizeof(uint64_t); i < max_digit_without_overflow; i++) {
mantissa = mantissa * 10 + digits[i]; // can be accelerated mantissa = mantissa * 10 + digits[i]; // can be accelerated
} }
return mantissa; return mantissa;
} }
// generate an exponent matching to_truncated_mantissa() // Generate san exponent matching to_truncated_mantissa()
inline int64_t to_truncated_exponent() { inline int32_t to_truncated_exponent() {
const int64_t max_digit_with_overflow = 19; return decimal_point - max_digit_without_overflow;
return decimal_point - max_digit_with_overflow;
} }
}; };