@@ -22,8 +22,8 @@ namespace numberparsing {
22
22
// true, negate the result.
23
23
// This function will only work in some cases, when it does not work, success is
24
24
// set to false. This should work *most of the time* (like 99% of the time).
25
- // We assume that power is in the [simdjson_smallest_power ,
26
- // simdjson_largest_power ] interval: the caller is responsible for this check.
25
+ // We assume that power is in the [smallest_power ,
26
+ // largest_power ] interval: the caller is responsible for this check.
27
27
simdjson_really_inline bool compute_float_64 (int64_t power, uint64_t i, bool negative, double &d) {
28
28
// we start with a fast path
29
29
// It was described in
@@ -124,27 +124,32 @@ simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool neg
124
124
// We are going to need to do some 64-bit arithmetic to get a precise product.
125
125
// We use a table lookup approach.
126
126
// It is safe because
127
- // power >= simdjson_smallest_power
128
- // and power <= simdjson_largest_power
127
+ // power >= smallest_power
128
+ // and power <= largest_power
129
129
// We recover the mantissa of the power, it has a leading 1. It is always
130
130
// rounded down.
131
131
//
132
132
// We want the most significant 64 bits of the product. We know
133
133
// this will be non-zero because the most significant bit of i is
134
134
// 1.
135
- const uint32_t index = 2 * uint32_t (power - simdjson_smallest_power );
135
+ const uint32_t index = 2 * uint32_t (power - smallest_power );
136
136
value128 firstproduct = full_multiplication (i, power_of_five_128[index ]);
137
- value128 secondproduct = full_multiplication (i, power_of_five_128[index + 1 ]);
138
- firstproduct.low += secondproduct.high ;
139
- if (secondproduct.high > firstproduct.low ) { firstproduct.high ++; }
137
+ // Unless the least significant 9 bits of the high (64-bit) part of the full
138
+ // product are all 1s, then we know that the most significant 54 bits are
139
+ // exact and no further work is needed.
140
+ if ((firstproduct.high & 0x1FF ) == 0x1FF ) {
141
+ value128 secondproduct = full_multiplication (i, power_of_five_128[index + 1 ]);
142
+ firstproduct.low += secondproduct.high ;
143
+ if (secondproduct.high > firstproduct.low ) { firstproduct.high ++; }
144
+ // At this point, we might need to add at most one to firstproduct, but this
145
+ // can only change the value of firstproduct.high if firstproduct.low is maximal.
146
+ if (simdjson_unlikely (firstproduct.low == 0xFFFFFFFFFFFFFFFF )) {
147
+ // This is very unlikely, but if so, we need to do much more work!
148
+ return false ;
149
+ }
150
+ }
140
151
uint64_t lower = firstproduct.low ;
141
152
uint64_t upper = firstproduct.high ;
142
- // At this point, we might need to add at most one to firstproduct, but this
143
- // can only change the value of firstproduct.high if firstproduct.low is maximal.
144
- if (simdjson_unlikely (firstproduct.low == 0xFFFFFFFFFFFFFFFF )) {
145
- // This is very unlikely, but if so, we need to do much more work!
146
- return false ;
147
- }
148
153
// The final mantissa should be 53 bits with a leading 1.
149
154
// We shift it so that it occupies 54 bits with a leading 1.
150
155
// /////
@@ -379,7 +384,7 @@ simdjson_really_inline error_code write_float(const uint8_t *const src, bool neg
379
384
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
380
385
// way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331
381
386
// To future reader: we'd love if someone found a better way, or at least could explain this result!
382
- if (simdjson_unlikely (exponent < simdjson_smallest_power ) || (exponent > simdjson_largest_power )) {
387
+ if (simdjson_unlikely (exponent < smallest_power ) || (exponent > largest_power )) {
383
388
// this is almost never going to get called!!!
384
389
// we start anew, going slowly!!!
385
390
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
@@ -705,7 +710,7 @@ SIMDJSON_UNUSED simdjson_really_inline simdjson_result<double> parse_double(cons
705
710
if (p-start_exp_digits == 0 || p-start_exp_digits > 19 ) { return NUMBER_ERROR; }
706
711
707
712
exponent += exp_neg ? 0 -exp : exp ;
708
- overflow = overflow || exponent < simdjson_smallest_power || exponent > simdjson_largest_power ;
713
+ overflow = overflow || exponent < smallest_power || exponent > largest_power ;
709
714
}
710
715
711
716
//
0 commit comments