@@ -8,14 +8,14 @@ namespace numberparsing {
8
8
9
9
#ifdef JSON_TEST_NUMBERS
10
10
#define INVALID_NUMBER (SRC ) (found_invalid_number((SRC)), NUMBER_ERROR)
11
- #define WRITE_INTEGER (VALUE, SRC, WRITER ) (found_integer((VALUE), (SRC)), writer .append_s64((VALUE)))
12
- #define WRITE_UNSIGNED (VALUE, SRC, WRITER ) (found_unsigned_integer((VALUE), (SRC)), writer .append_u64((VALUE)))
13
- #define WRITE_DOUBLE (VALUE, SRC, WRITER ) (found_float((VALUE), (SRC)), writer .append_double((VALUE)))
11
+ #define WRITE_INTEGER (VALUE, SRC, WRITER ) (found_integer((VALUE), (SRC)), (WRITER) .append_s64((VALUE)))
12
+ #define WRITE_UNSIGNED (VALUE, SRC, WRITER ) (found_unsigned_integer((VALUE), (SRC)), (WRITER) .append_u64((VALUE)))
13
+ #define WRITE_DOUBLE (VALUE, SRC, WRITER ) (found_float((VALUE), (SRC)), (WRITER) .append_double((VALUE)))
14
14
#else
15
15
#define INVALID_NUMBER (SRC ) (NUMBER_ERROR)
16
- #define WRITE_INTEGER (VALUE, SRC, WRITER ) writer .append_s64((VALUE))
17
- #define WRITE_UNSIGNED (VALUE, SRC, WRITER ) writer .append_u64((VALUE))
18
- #define WRITE_DOUBLE (VALUE, SRC, WRITER ) writer .append_double((VALUE))
16
+ #define WRITE_INTEGER (VALUE, SRC, WRITER ) (WRITER) .append_s64((VALUE))
17
+ #define WRITE_UNSIGNED (VALUE, SRC, WRITER ) (WRITER) .append_u64((VALUE))
18
+ #define WRITE_DOUBLE (VALUE, SRC, WRITER ) (WRITER) .append_double((VALUE))
19
19
#endif
20
20
21
21
// Attempts to compute i * 10^(power) exactly; and if "negative" is
@@ -250,7 +250,7 @@ template<typename W>
250
250
error_code slow_float_parsing (SIMDJSON_UNUSED const uint8_t * src, W writer) {
251
251
double d;
252
252
if (parse_float_strtod (src, &d)) {
253
- WRITE_DOUBLE (d, src, writer );
253
+ writer. append_double (d );
254
254
return SUCCESS;
255
255
}
256
256
return INVALID_NUMBER (src);
@@ -345,35 +345,36 @@ simdjson_really_inline error_code parse_exponent(SIMDJSON_UNUSED const uint8_t *
345
345
return SUCCESS;
346
346
}
347
347
348
+ simdjson_really_inline int significant_digits (const uint8_t * start_digits, int digit_count) {
349
+ // It is possible that the integer had an overflow.
350
+ // We have to handle the case where we have 0.0000somenumber.
351
+ const uint8_t *start = start_digits;
352
+ while ((*start == ' 0' ) || (*start == ' .' )) {
353
+ start++;
354
+ }
355
+ // we over-decrement by one when there is a '.'
356
+ return digit_count - int (start - start_digits);
357
+ }
358
+
348
359
template <typename W>
349
360
simdjson_really_inline error_code write_float (const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, int digit_count, int64_t exponent, W &writer) {
350
361
// If we frequently had to deal with long strings of digits,
351
362
// we could extend our code by using a 128-bit integer instead
352
363
// of a 64-bit integer. However, this is uncommon in practice.
353
364
// digit count is off by 1 because of the decimal (assuming there was one).
354
- if (simdjson_unlikely ((digit_count-1 >= 19 ))) { // this is uncommon
355
- // It is possible that the integer had an overflow.
356
- // We have to handle the case where we have 0.0000somenumber.
357
- const uint8_t *start = start_digits;
358
- while ((*start == ' 0' ) || (*start == ' .' )) {
359
- start++;
360
- }
361
- // we over-decrement by one when there is a '.'
362
- digit_count -= int (start - start_digits);
363
- if (digit_count >= 19 ) {
364
- // Ok, chances are good that we had an overflow!
365
- // this is almost never going to get called!!!
366
- // we start anew, going slowly!!!
367
- // This will happen in the following examples:
368
- // 10000000000000000000000000000000000000000000e+308
369
- // 3.1415926535897932384626433832795028841971693993751
370
- //
371
- error_code error = slow_float_parsing (src, writer);
372
- // The number was already written, but we made a copy of the writer
373
- // when we passed it to the parse_large_integer() function, so
374
- writer.skip_double ();
375
- return error;
376
- }
365
+ if (simdjson_unlikely (digit_count-1 >= 19 && significant_digits (start_digits, digit_count) >= 19 )) {
366
+ // Ok, chances are good that we had an overflow!
367
+ // this is almost never going to get called!!!
368
+ // we start anew, going slowly!!!
369
+ // This will happen in the following examples:
370
+ // 10000000000000000000000000000000000000000000e+308
371
+ // 3.1415926535897932384626433832795028841971693993751
372
+ //
373
+ error_code error = slow_float_parsing (src, writer);
374
+ // The number was already written, but we made a copy of the writer
375
+ // when we passed it to the parse_large_integer() function, so
376
+ writer.skip_double ();
377
+ return error;
377
378
}
378
379
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
379
380
// way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331
0 commit comments