Skip to content

Commit e1ab2c9

Browse files
committed
This simplifies the number parsing routine. It may or may not be a win.
1 parent 7fc07e2 commit e1ab2c9

File tree

2 files changed

+681
-687
lines changed

2 files changed

+681
-687
lines changed

src/generic/stage2/numberparsing.h

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,6 @@ simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool neg
8888
return true;
8989
}
9090

91-
// We are going to need to do some 64-bit arithmetic to get a more precise product.
92-
// We use a table lookup approach.
93-
// It is safe because
94-
// power >= FASTFLOAT_SMALLEST_POWER
95-
// and power <= FASTFLOAT_LARGEST_POWER
96-
// We recover the mantissa of the power, it has a leading 1. It is always
97-
// rounded down.
98-
uint64_t factor_mantissa = mantissa_64[power - FASTFLOAT_SMALLEST_POWER];
9991

10092
// The exponent is 1024 + 63 + power
10193
// + floor(log(5**power)/log(2)).
@@ -127,43 +119,33 @@ simdjson_really_inline bool compute_float_64(int64_t power, uint64_t i, bool neg
127119
// We want the most significant bit of i to be 1. Shift if needed.
128120
int lz = leading_zeroes(i);
129121
i <<= lz;
122+
123+
124+
// We are going to need to do some 64-bit arithmetic to get a precise product.
125+
// We use a table lookup approach.
126+
// It is safe because
127+
// power >= FASTFLOAT_SMALLEST_POWER
128+
// and power <= FASTFLOAT_LARGEST_POWER
129+
// We recover the mantissa of the power, it has a leading 1. It is always
130+
// rounded down.
131+
//
130132
// We want the most significant 64 bits of the product. We know
131133
// this will be non-zero because the most significant bit of i is
132134
// 1.
133-
value128 product = full_multiplication(i, factor_mantissa);
134-
uint64_t lower = product.low;
135-
uint64_t upper = product.high;
136-
137-
// We know that upper has at most one leading zero because
138-
// both i and factor_mantissa have a leading one. This means
139-
// that the result is at least as large as ((1<<63)*(1<<63))/(1<<64).
140-
141-
// As long as the first 9 bits of "upper" are not "1", then we
142-
// know that we have an exact computed value for the leading
143-
// 55 bits because any imprecision would play out as a +1, in
144-
// the worst case.
145-
if (simdjson_unlikely((upper & 0x1FF) == 0x1FF) && (lower + i < lower)) {
146-
uint64_t factor_mantissa_low =
147-
mantissa_128[power - FASTFLOAT_SMALLEST_POWER];
148-
// next, we compute the 64-bit x 128-bit multiplication, getting a 192-bit
149-
// result (three 64-bit values)
150-
product = full_multiplication(i, factor_mantissa_low);
151-
uint64_t product_low = product.low;
152-
uint64_t product_middle2 = product.high;
153-
uint64_t product_middle1 = lower;
154-
uint64_t product_high = upper;
155-
uint64_t product_middle = product_middle1 + product_middle2;
156-
if (product_middle < product_middle1) {
157-
product_high++; // overflow carry
158-
}
159-
// We want to check whether mantissa *i + i would affect our result.
160-
// This does happen, e.g. with 7.3177701707893310e+15.
161-
if (((product_middle + 1 == 0) && ((product_high & 0x1FF) == 0x1FF) &&
162-
(product_low + i < product_low))) { // let us be prudent and bail out.
163-
return false;
164-
}
165-
upper = product_high;
166-
lower = product_middle;
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]);
138+
firstproduct.low += secondproduct.high;
139+
if(secondproduct.high > firstproduct.low) {
140+
firstproduct.high++;
141+
}
142+
uint64_t lower = firstproduct.low;
143+
uint64_t upper = 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(firstproduct.low == 0xFFFFFFFFFFFFFFFF) {
147+
// This is very unlikely, but if so, we need to do much more work!
148+
return false;
167149
}
168150
// The final mantissa should be 53 bits with a leading 1.
169151
// We shift it so that it occupies 54 bits with a leading 1.

0 commit comments

Comments
 (0)