Skip to content

Commit 534632d

Browse files
authored
Minor tweak on number parsing (simdjson#1041)
* Tweak.
1 parent 8bf5f3d commit 534632d

File tree

1 file changed

+8
-12
lines changed

1 file changed

+8
-12
lines changed

src/generic/stage2/numberparsing.h

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -437,17 +437,13 @@ really_inline bool parse_number(const uint8_t *const src, W &writer) {
437437
int longest_digit_count = negative ? 19 : 20;
438438
if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); }
439439
if (digit_count == longest_digit_count) {
440-
// Anything negative above INT64_MAX is either invalid or INT64_MIN.
441-
if (negative && i > uint64_t(INT64_MAX)) {
442-
// If the number is negative and can't fit in a signed integer, it's invalid.
443-
if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); }
444-
445-
// If it's negative, it has to be INT64_MAX+1 now (or INT64_MIN).
446-
// C++ can't reliably negate uint64_t INT64_MIN, it seems. Special case it.
447-
WRITE_INTEGER(INT64_MIN, src, writer);
440+
if(negative) {
441+
// Anything negative above INT64_MAX+1 is invalid
442+
if (i > uint64_t(INT64_MAX)+1) {
443+
return INVALID_NUMBER(src);
444+
}
445+
WRITE_INTEGER(~i+1, src, writer);
448446
return is_structural_or_whitespace(*p);
449-
}
450-
451447
// Positive overflow check:
452448
// - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the
453449
// biggest uint64_t.
@@ -460,14 +456,14 @@ really_inline bool parse_number(const uint8_t *const src, W &writer) {
460456
// - Therefore, if the number is positive and lower than that, it's overflow.
461457
// - The value we are looking at is less than or equal to 9,223,372,036,854,775,808 (INT64_MAX).
462458
//
463-
if (!negative && (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX))) { return INVALID_NUMBER(src); }
459+
} else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); }
464460
}
465461

466462
// Write unsigned if it doesn't fit in a signed integer.
467463
if (i > uint64_t(INT64_MAX)) {
468464
WRITE_UNSIGNED(i, src, writer);
469465
} else {
470-
WRITE_INTEGER(negative ? 0 - i : i, src, writer);
466+
WRITE_INTEGER(negative ? (~i+1) : i, src, writer);
471467
}
472468
return is_structural_or_whitespace(*p);
473469
}

0 commit comments

Comments
 (0)