@@ -24,7 +24,7 @@ namespace numberparsing {
24
24
// set to false. This should work *most of the time* (like 99% of the time).
25
25
// We assume that power is in the [FASTFLOAT_SMALLEST_POWER,
26
26
// FASTFLOAT_LARGEST_POWER] interval: the caller is responsible for this check.
27
- simdjson_really_inline double compute_float_64 (int64_t power, uint64_t i, bool negative, bool *success ) {
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
30
30
// Clinger WD. How to read floating point numbers accurately.
@@ -40,7 +40,7 @@ simdjson_really_inline double compute_float_64(int64_t power, uint64_t i, bool n
40
40
#endif
41
41
// convert the integer into a double. This is lossless since
42
42
// 0 <= i <= 2^53 - 1.
43
- double d = double (i);
43
+ d = double (i);
44
44
//
45
45
// The general idea is as follows.
46
46
// If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then
@@ -59,8 +59,7 @@ simdjson_really_inline double compute_float_64(int64_t power, uint64_t i, bool n
59
59
if (negative) {
60
60
d = -d;
61
61
}
62
- *success = true ;
63
- return d;
62
+ return true ;
64
63
}
65
64
// When 22 < power && power < 22 + 16, we could
66
65
// hope for another, secondary fast path. It wa
@@ -85,7 +84,8 @@ simdjson_really_inline double compute_float_64(int64_t power, uint64_t i, bool n
85
84
// In the slow path, we need to adjust i so that it is > 1<<63 which is always
86
85
// possible, except if i == 0, so we handle i == 0 separately.
87
86
if (i == 0 ) {
88
- return 0.0 ;
87
+ d = 0.0 ;
88
+ return true ;
89
89
}
90
90
91
91
// We are going to need to do some 64-bit arithmetic to get a more precise product.
@@ -135,8 +135,7 @@ simdjson_really_inline double compute_float_64(int64_t power, uint64_t i, bool n
135
135
// This does happen, e.g. with 7.3177701707893310e+15.
136
136
if (((product_middle + 1 == 0 ) && ((product_high & 0x1FF ) == 0x1FF ) &&
137
137
(product_low + i < product_low))) { // let us be prudent and bail out.
138
- *success = false ;
139
- return 0 ;
138
+ return false ;
140
139
}
141
140
upper = product_high;
142
141
lower = product_middle;
@@ -157,25 +156,24 @@ simdjson_really_inline double compute_float_64(int64_t power, uint64_t i, bool n
157
156
// floating-point values.
158
157
if (simdjson_unlikely ((lower == 0 ) && ((upper & 0x1FF ) == 0 ) &&
159
158
((mantissa & 3 ) == 1 ))) {
160
- // if mantissa & 1 == 1 we might need to round up.
161
- //
162
- // Scenarios:
163
- // 1. We are not in the middle. Then we should round up.
164
- //
165
- // 2. We are right in the middle. Whether we round up depends
166
- // on the last significant bit: if it is "one" then we round
167
- // up (round to even) otherwise, we do not.
168
- //
169
- // So if the last significant bit is 1, we can safely round up.
170
- // Hence we only need to bail out if (mantissa & 3) == 1.
171
- // Otherwise we may need more accuracy or analysis to determine whether
172
- // we are exactly between two floating-point numbers.
173
- // It can be triggered with 1e23.
174
- // Note: because the factor_mantissa and factor_mantissa_low are
175
- // almost always rounded down (except for small positive powers),
176
- // almost always should round up.
177
- *success = false ;
178
- return 0 ;
159
+ // if mantissa & 1 == 1 we might need to round up.
160
+ //
161
+ // Scenarios:
162
+ // 1. We are not in the middle. Then we should round up.
163
+ //
164
+ // 2. We are right in the middle. Whether we round up depends
165
+ // on the last significant bit: if it is "one" then we round
166
+ // up (round to even) otherwise, we do not.
167
+ //
168
+ // So if the last significant bit is 1, we can safely round up.
169
+ // Hence we only need to bail out if (mantissa & 3) == 1.
170
+ // Otherwise we may need more accuracy or analysis to determine whether
171
+ // we are exactly between two floating-point numbers.
172
+ // It can be triggered with 1e23.
173
+ // Note: because the factor_mantissa and factor_mantissa_low are
174
+ // almost always rounded down (except for small positive powers),
175
+ // almost always should round up.
176
+ return false ;
179
177
}
180
178
181
179
mantissa += mantissa & 1 ;
@@ -193,15 +191,12 @@ simdjson_really_inline double compute_float_64(int64_t power, uint64_t i, bool n
193
191
uint64_t real_exponent = c.exp - lz;
194
192
// we have to check that real_exponent is in range, otherwise we bail out
195
193
if (simdjson_unlikely ((real_exponent < 1 ) || (real_exponent > 2046 ))) {
196
- *success = false ;
197
- return 0 ;
194
+ return false ;
198
195
}
199
196
mantissa |= real_exponent << 52 ;
200
197
mantissa |= (((uint64_t )negative) << 63 );
201
- double d;
202
198
memcpy (&d, &mantissa, sizeof (d));
203
- *success = true ;
204
- return d;
199
+ return true ;
205
200
}
206
201
207
202
static bool parse_float_strtod (const uint8_t *ptr, double *outDouble) {
@@ -392,9 +387,8 @@ simdjson_really_inline error_code write_float(const uint8_t *const src, bool neg
392
387
writer.skip_double ();
393
388
return error;
394
389
}
395
- bool success = true ;
396
- double d = compute_float_64 (exponent, i, negative, &success);
397
- if (!success) {
390
+ double d;
391
+ if (!compute_float_64 (exponent, i, negative, d)) {
398
392
// we are almost never going to get here.
399
393
if (!parse_float_strtod (src, &d)) { return INVALID_NUMBER (src); }
400
394
}
@@ -713,12 +707,10 @@ SIMDJSON_UNUSED simdjson_really_inline simdjson_result<double> parse_double(cons
713
707
//
714
708
// Assemble (or slow-parse) the float
715
709
//
710
+ double d;
716
711
if (simdjson_likely (!overflow)) {
717
- bool success = true ;
718
- double d = compute_float_64 (exponent, i, negative, &success);
719
- if (success) { return d; }
712
+ if (compute_float_64 (exponent, i, negative, d)) { return d; }
720
713
}
721
- double d;
722
714
if (!parse_float_strtod (src-negative, &d)) {
723
715
return NUMBER_ERROR;
724
716
}
0 commit comments