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