@@ -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 [FASTFLOAT_SMALLEST_POWER ,
26
- // FASTFLOAT_LARGEST_POWER ] interval: the caller is responsible for this check.
25
+ // We assume that power is in the [simdjson_smallest_power ,
26
+ // simdjson_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
@@ -61,6 +61,7 @@ simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool neg
61
61
}
62
62
return true ;
63
63
}
64
+ printf (" OOO\n " );
64
65
// When 22 < power && power < 22 + 16, we could
65
66
// hope for another, secondary fast path. It was
66
67
// described by David M. Gay in "Correctly rounded
@@ -124,26 +125,24 @@ simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool neg
124
125
// We are going to need to do some 64-bit arithmetic to get a precise product.
125
126
// We use a table lookup approach.
126
127
// It is safe because
127
- // power >= FASTFLOAT_SMALLEST_POWER
128
- // and power <= FASTFLOAT_LARGEST_POWER
128
+ // power >= simdjson_smallest_power
129
+ // and power <= simdjson_largest_power
129
130
// We recover the mantissa of the power, it has a leading 1. It is always
130
131
// rounded down.
131
132
//
132
133
// We want the most significant 64 bits of the product. We know
133
134
// this will be non-zero because the most significant bit of i is
134
135
// 1.
135
-
136
- value128 firstproduct = full_multiplication (i, power_of_five_128[2 * (power - FASTFLOAT_SMALLEST_POWER) ]);
137
- value128 secondproduct = full_multiplication (i, power_of_five_128[2 * (power - FASTFLOAT_SMALLEST_POWER) + 1 ]);
136
+ const uint32_t index = 2 * uint32_t (power - simdjson_smallest_power);
137
+ value128 firstproduct = full_multiplication (i, power_of_five_128[index ]);
138
+ value128 secondproduct = full_multiplication (i, power_of_five_128[index + 1 ]);
138
139
firstproduct.low += secondproduct.high ;
139
- if (secondproduct.high > firstproduct.low ) {
140
- firstproduct.high ++;
141
- }
140
+ if (secondproduct.high > firstproduct.low ) { firstproduct.high ++; }
142
141
uint64_t lower = firstproduct.low ;
143
142
uint64_t upper = firstproduct.high ;
144
143
// At this point, we might need to add at most one to firstproduct, but this
145
144
// can only change the value of firstproduct.high if firstproduct.low is maximal.
146
- if (firstproduct.low == 0xFFFFFFFFFFFFFFFF ) {
145
+ if (simdjson_unlikely ( firstproduct.low == 0xFFFFFFFFFFFFFFFF ) ) {
147
146
// This is very unlikely, but if so, we need to do much more work!
148
147
return false ;
149
148
}
@@ -161,26 +160,9 @@ simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool neg
161
160
// which we guard against.
162
161
// If we have lots of trailing zeros, we may fall right between two
163
162
// floating-point values.
164
- if (simdjson_unlikely ((lower == 0 ) && ((upper & 0x1FF ) == 0 ) &&
163
+ if (simdjson_unlikely ((lower == 0 ) && (power >= 0 ) && (power <= 23 ) && ( (upper & 0x1FF ) == 0 ) &&
165
164
((mantissa & 3 ) == 1 ))) {
166
- // if mantissa & 1 == 1 we might need to round up.
167
- //
168
- // Scenarios:
169
- // 1. We are not in the middle. Then we should round up.
170
- //
171
- // 2. We are right in the middle. Whether we round up depends
172
- // on the last significant bit: if it is "one" then we round
173
- // up (round to even) otherwise, we do not.
174
- //
175
- // So if the last significant bit is 1, we can safely round up.
176
- // Hence we only need to bail out if (mantissa & 3) == 1.
177
- // Otherwise we may need more accuracy or analysis to determine whether
178
- // we are exactly between two floating-point numbers.
179
- // It can be triggered with 1e23.
180
- // Note: because the factor_mantissa and factor_mantissa_low are
181
- // almost always rounded down (except for small positive powers),
182
- // almost always should round up.
183
- return false ;
165
+ mantissa ^= 1 ; // flip it so that we do not round up
184
166
}
185
167
186
168
mantissa += mantissa & 1 ;
@@ -398,7 +380,7 @@ simdjson_really_inline error_code write_float(const uint8_t *const src, bool neg
398
380
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
399
381
// way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331
400
382
// To future reader: we'd love if someone found a better way, or at least could explain this result!
401
- if (simdjson_unlikely (exponent < FASTFLOAT_SMALLEST_POWER ) || (exponent > FASTFLOAT_LARGEST_POWER )) {
383
+ if (simdjson_unlikely (exponent < simdjson_smallest_power ) || (exponent > simdjson_largest_power )) {
402
384
// this is almost never going to get called!!!
403
385
// we start anew, going slowly!!!
404
386
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
@@ -724,7 +706,7 @@ SIMDJSON_UNUSED simdjson_really_inline simdjson_result<double> parse_double(cons
724
706
if (p-start_exp_digits == 0 || p-start_exp_digits > 19 ) { return NUMBER_ERROR; }
725
707
726
708
exponent += exp_neg ? 0 -exp : exp ;
727
- overflow = overflow || exponent < FASTFLOAT_SMALLEST_POWER || exponent > FASTFLOAT_LARGEST_POWER ;
709
+ overflow = overflow || exponent < simdjson_smallest_power || exponent > simdjson_largest_power ;
728
710
}
729
711
730
712
//
0 commit comments