Skip to content

Commit 53ad445

Browse files
committed
Minor tweaks.
1 parent 050987e commit 53ad445

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

src/generic/stage2/numberparsing.h

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ namespace numberparsing {
2222
// true, negate the result.
2323
// This function will only work in some cases, when it does not work, success is
2424
// 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.
2727
simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) {
2828
// we start with a fast path
2929
// It was described in
@@ -124,27 +124,32 @@ simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool neg
124124
// We are going to need to do some 64-bit arithmetic to get a precise product.
125125
// We use a table lookup approach.
126126
// It is safe because
127-
// power >= simdjson_smallest_power
128-
// and power <= simdjson_largest_power
127+
// power >= smallest_power
128+
// and power <= largest_power
129129
// We recover the mantissa of the power, it has a leading 1. It is always
130130
// rounded down.
131131
//
132132
// We want the most significant 64 bits of the product. We know
133133
// this will be non-zero because the most significant bit of i is
134134
// 1.
135-
const uint32_t index = 2 * uint32_t(power - simdjson_smallest_power);
135+
const uint32_t index = 2 * uint32_t(power - smallest_power);
136136
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+
}
140151
uint64_t lower = firstproduct.low;
141152
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-
}
148153
// The final mantissa should be 53 bits with a leading 1.
149154
// We shift it so that it occupies 54 bits with a leading 1.
150155
///////
@@ -379,7 +384,7 @@ simdjson_really_inline error_code write_float(const uint8_t *const src, bool neg
379384
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
380385
// way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331
381386
// 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)) {
383388
// this is almost never going to get called!!!
384389
// we start anew, going slowly!!!
385390
// 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
705710
if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; }
706711

707712
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;
709714
}
710715

711716
//

src/jsoncharutils_tables.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ const uint32_t digit_to_val32[886] = {
201201
// per instruction set).
202202
///
203203

204-
constexpr int simdjson_smallest_power = -344;
205-
constexpr int simdjson_largest_power = 308;
204+
constexpr int smallest_power = -344;
205+
constexpr int largest_power = 308;
206206

207207
struct value128 {
208208
uint64_t low;

0 commit comments

Comments
 (0)