| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
// Copyright 2019 Ulf Adams |
|
2
|
|
|
|
|
|
|
// |
|
3
|
|
|
|
|
|
|
// The contents of this file may be used under the terms of the Apache License, |
|
4
|
|
|
|
|
|
|
// Version 2.0. |
|
5
|
|
|
|
|
|
|
// |
|
6
|
|
|
|
|
|
|
// (See accompanying file LICENSE-Apache or copy at |
|
7
|
|
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0) |
|
8
|
|
|
|
|
|
|
// |
|
9
|
|
|
|
|
|
|
// Alternatively, the contents of this file may be used under the terms of |
|
10
|
|
|
|
|
|
|
// the Boost Software License, Version 1.0. |
|
11
|
|
|
|
|
|
|
// (See accompanying file LICENSE-Boost or copy at |
|
12
|
|
|
|
|
|
|
// https://www.boost.org/LICENSE_1_0.txt) |
|
13
|
|
|
|
|
|
|
// |
|
14
|
|
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, this software |
|
15
|
|
|
|
|
|
|
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
16
|
|
|
|
|
|
|
// KIND, either express or implied. |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
/* The location of the headers, relative to this file, has been changed by |
|
19
|
|
|
|
|
|
|
* Sisyphus */ |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
#include "ryu_headers/ryu_parse.h" |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#include |
|
24
|
|
|
|
|
|
|
#include |
|
25
|
|
|
|
|
|
|
#include |
|
26
|
|
|
|
|
|
|
#include |
|
27
|
|
|
|
|
|
|
#include |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
#ifdef RYU_DEBUG |
|
30
|
|
|
|
|
|
|
#include |
|
31
|
|
|
|
|
|
|
#include |
|
32
|
|
|
|
|
|
|
#endif |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
#include "ryu_headers/common.h" |
|
35
|
|
|
|
|
|
|
#include "ryu_headers/d2s_intrinsics.h" |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
#if defined(RYU_OPTIMIZE_SIZE) |
|
38
|
|
|
|
|
|
|
#include "ryu_headers/d2s_small_table.h" |
|
39
|
|
|
|
|
|
|
#else |
|
40
|
|
|
|
|
|
|
#include "ryu_headers/d2s_full_table.h" |
|
41
|
|
|
|
|
|
|
#endif |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
#define DOUBLE_MANTISSA_BITS 52 |
|
44
|
|
|
|
|
|
|
#define DOUBLE_EXPONENT_BITS 11 |
|
45
|
|
|
|
|
|
|
#define DOUBLE_EXPONENT_BIAS 1023 |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
#if defined(_MSC_VER) |
|
48
|
|
|
|
|
|
|
#include |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
static inline uint32_t floor_log2(const uint64_t value) { |
|
51
|
|
|
|
|
|
|
#if !defined(_WIN64) /* _BitScanReverse64 unavailable */ |
|
52
|
|
|
|
|
|
|
long index = 0; |
|
53
|
|
|
|
|
|
|
uint64_t v = value; |
|
54
|
|
|
|
|
|
|
if(!v) return 64; |
|
55
|
|
|
|
|
|
|
while(v >>= 1) index += 1; |
|
56
|
|
|
|
|
|
|
return index; |
|
57
|
|
|
|
|
|
|
#else |
|
58
|
|
|
|
|
|
|
long index; |
|
59
|
|
|
|
|
|
|
return _BitScanReverse64(&index, value) ? index : 64; |
|
60
|
|
|
|
|
|
|
#endif |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
#else |
|
64
|
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
|
static inline uint32_t floor_log2(const uint64_t value) { |
|
66
|
0
|
|
|
|
|
|
return 63 - __builtin_clzll(value); |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
#endif |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
// The max function is already defined on Windows. |
|
72
|
0
|
|
|
|
|
|
static inline int32_t max32(int32_t a, int32_t b) { |
|
73
|
0
|
|
|
|
|
|
return a < b ? b : a; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
0
|
|
|
|
|
|
static inline double int64Bits2Double(uint64_t bits) { |
|
77
|
|
|
|
|
|
|
double f; |
|
78
|
0
|
|
|
|
|
|
memcpy(&f, &bits, sizeof(double)); |
|
79
|
0
|
|
|
|
|
|
return f; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
enum Status s2d_n(const char * buffer, const int len, double * result) { |
|
83
|
0
|
0
|
|
|
|
|
if (len == 0) { |
|
84
|
0
|
|
|
|
|
|
return INPUT_TOO_SHORT; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
0
|
|
|
|
|
|
int m10digits = 0; |
|
87
|
0
|
|
|
|
|
|
int e10digits = 0; |
|
88
|
0
|
|
|
|
|
|
int dotIndex = len; |
|
89
|
0
|
|
|
|
|
|
int eIndex = len; |
|
90
|
0
|
|
|
|
|
|
uint64_t m10 = 0; |
|
91
|
0
|
|
|
|
|
|
int32_t e10 = 0; |
|
92
|
0
|
|
|
|
|
|
bool signedM = false; |
|
93
|
0
|
|
|
|
|
|
bool signedE = false; |
|
94
|
0
|
|
|
|
|
|
int i = 0; |
|
95
|
0
|
0
|
|
|
|
|
if (buffer[i] == '-') { |
|
96
|
0
|
|
|
|
|
|
signedM = true; |
|
97
|
0
|
|
|
|
|
|
i++; |
|
98
|
|
|
|
|
|
|
} |
|
99
|
0
|
0
|
|
|
|
|
for (; i < len; i++) { |
|
100
|
0
|
|
|
|
|
|
char c = buffer[i]; |
|
101
|
0
|
0
|
|
|
|
|
if (c == '.') { |
|
102
|
0
|
0
|
|
|
|
|
if (dotIndex != len) { |
|
103
|
0
|
|
|
|
|
|
return MALFORMED_INPUT; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
0
|
|
|
|
|
|
dotIndex = i; |
|
106
|
0
|
|
|
|
|
|
continue; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
0
|
0
|
|
|
|
|
if ((c < '0') || (c > '9')) { |
|
|
|
0
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
break; |
|
110
|
|
|
|
|
|
|
} |
|
111
|
0
|
0
|
|
|
|
|
if (m10digits >= 17) { |
|
112
|
0
|
|
|
|
|
|
return INPUT_TOO_LONG; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
0
|
|
|
|
|
|
m10 = 10 * m10 + (c - '0'); |
|
115
|
0
|
0
|
|
|
|
|
if (m10 != 0) { |
|
116
|
0
|
|
|
|
|
|
m10digits++; |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
} |
|
119
|
0
|
0
|
|
|
|
|
if (i < len && ((buffer[i] == 'e') || (buffer[i] == 'E'))) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
120
|
0
|
|
|
|
|
|
eIndex = i; |
|
121
|
0
|
|
|
|
|
|
i++; |
|
122
|
0
|
0
|
|
|
|
|
if (i < len && ((buffer[i] == '-') || (buffer[i] == '+'))) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
123
|
0
|
|
|
|
|
|
signedE = buffer[i] == '-'; |
|
124
|
0
|
|
|
|
|
|
i++; |
|
125
|
|
|
|
|
|
|
} |
|
126
|
0
|
0
|
|
|
|
|
for (; i < len; i++) { |
|
127
|
0
|
|
|
|
|
|
char c = buffer[i]; |
|
128
|
0
|
0
|
|
|
|
|
if ((c < '0') || (c > '9')) { |
|
|
|
0
|
|
|
|
|
|
|
129
|
0
|
|
|
|
|
|
return MALFORMED_INPUT; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
0
|
0
|
|
|
|
|
if (e10digits > 3) { |
|
132
|
|
|
|
|
|
|
// TODO: Be more lenient. Return +/-Infinity or +/-0 instead. |
|
133
|
0
|
|
|
|
|
|
return INPUT_TOO_LONG; |
|
134
|
|
|
|
|
|
|
} |
|
135
|
0
|
|
|
|
|
|
e10 = 10 * e10 + (c - '0'); |
|
136
|
0
|
0
|
|
|
|
|
if (e10 != 0) { |
|
137
|
0
|
|
|
|
|
|
e10digits++; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
} |
|
141
|
0
|
0
|
|
|
|
|
if (i < len) { |
|
142
|
0
|
|
|
|
|
|
return MALFORMED_INPUT; |
|
143
|
|
|
|
|
|
|
} |
|
144
|
0
|
0
|
|
|
|
|
if (signedE) { |
|
145
|
0
|
|
|
|
|
|
e10 = -e10; |
|
146
|
|
|
|
|
|
|
} |
|
147
|
0
|
0
|
|
|
|
|
e10 -= dotIndex < eIndex ? eIndex - dotIndex - 1 : 0; |
|
148
|
0
|
0
|
|
|
|
|
if (m10 == 0) { |
|
149
|
0
|
0
|
|
|
|
|
*result = signedM ? -0.0 : 0.0; |
|
150
|
0
|
|
|
|
|
|
return SUCCESS; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
#ifdef RYU_DEBUG |
|
154
|
0
|
|
|
|
|
|
printf("Input=%s\n", buffer); |
|
155
|
0
|
|
|
|
|
|
printf("m10digits = %d\n", m10digits); |
|
156
|
0
|
|
|
|
|
|
printf("e10digits = %d\n", e10digits); |
|
157
|
0
|
|
|
|
|
|
printf("m10 * 10^e10 = %" PRIu64 " * 10^%d\n", m10, e10); |
|
158
|
|
|
|
|
|
|
#endif |
|
159
|
|
|
|
|
|
|
|
|
160
|
0
|
0
|
|
|
|
|
if ((m10digits + e10 <= -324) || (m10 == 0)) { |
|
|
|
0
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
// Number is less than 1e-324, which should be rounded down to 0; return +/-0.0. |
|
162
|
0
|
|
|
|
|
|
uint64_t ieee = ((uint64_t) signedM) << (DOUBLE_EXPONENT_BITS + DOUBLE_MANTISSA_BITS); |
|
163
|
0
|
|
|
|
|
|
*result = int64Bits2Double(ieee); |
|
164
|
0
|
|
|
|
|
|
return SUCCESS; |
|
165
|
|
|
|
|
|
|
} |
|
166
|
0
|
0
|
|
|
|
|
if (m10digits + e10 >= 310) { |
|
167
|
|
|
|
|
|
|
// Number is larger than 1e+309, which should be rounded to +/-Infinity. |
|
168
|
0
|
|
|
|
|
|
uint64_t ieee = (((uint64_t) signedM) << (DOUBLE_EXPONENT_BITS + DOUBLE_MANTISSA_BITS)) | (0x7ffull << DOUBLE_MANTISSA_BITS); |
|
169
|
0
|
|
|
|
|
|
*result = int64Bits2Double(ieee); |
|
170
|
0
|
|
|
|
|
|
return SUCCESS; |
|
171
|
|
|
|
|
|
|
} |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
// Convert to binary float m2 * 2^e2, while retaining information about whether the conversion |
|
174
|
|
|
|
|
|
|
// was exact (trailingZeros). |
|
175
|
|
|
|
|
|
|
int32_t e2; |
|
176
|
|
|
|
|
|
|
uint64_t m2; |
|
177
|
|
|
|
|
|
|
bool trailingZeros; |
|
178
|
0
|
0
|
|
|
|
|
if (e10 >= 0) { |
|
179
|
|
|
|
|
|
|
// The length of m * 10^e in bits is: |
|
180
|
|
|
|
|
|
|
// log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + e10 * log2(5) |
|
181
|
|
|
|
|
|
|
// |
|
182
|
|
|
|
|
|
|
// We want to compute the DOUBLE_MANTISSA_BITS + 1 top-most bits (+1 for the implicit leading |
|
183
|
|
|
|
|
|
|
// one in IEEE format). We therefore choose a binary output exponent of |
|
184
|
|
|
|
|
|
|
// log2(m10 * 10^e10) - (DOUBLE_MANTISSA_BITS + 1). |
|
185
|
|
|
|
|
|
|
// |
|
186
|
|
|
|
|
|
|
// We use floor(log2(5^e10)) so that we get at least this many bits; better to |
|
187
|
|
|
|
|
|
|
// have an additional bit than to not have enough bits. |
|
188
|
0
|
|
|
|
|
|
e2 = floor_log2(m10) + e10 + log2pow5(e10) - (DOUBLE_MANTISSA_BITS + 1); |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
// We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)]. |
|
191
|
|
|
|
|
|
|
// To that end, we use the DOUBLE_POW5_SPLIT table. |
|
192
|
0
|
|
|
|
|
|
int j = e2 - e10 - ceil_log2pow5(e10) + DOUBLE_POW5_BITCOUNT; |
|
193
|
0
|
0
|
|
|
|
|
assert(j >= 0); |
|
194
|
|
|
|
|
|
|
#if defined(RYU_OPTIMIZE_SIZE) |
|
195
|
|
|
|
|
|
|
uint64_t pow5[2]; |
|
196
|
|
|
|
|
|
|
double_computePow5(e10, pow5); |
|
197
|
|
|
|
|
|
|
m2 = mulShift64(m10, pow5, j); |
|
198
|
|
|
|
|
|
|
#else |
|
199
|
0
|
0
|
|
|
|
|
assert(e10 < DOUBLE_POW5_TABLE_SIZE); |
|
200
|
0
|
|
|
|
|
|
m2 = mulShift64(m10, DOUBLE_POW5_SPLIT[e10], j); |
|
201
|
|
|
|
|
|
|
#endif |
|
202
|
|
|
|
|
|
|
// We also compute if the result is exact, i.e., |
|
203
|
|
|
|
|
|
|
// [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2. |
|
204
|
|
|
|
|
|
|
// This can only be the case if 2^e2 divides m10 * 10^e10, which in turn requires that the |
|
205
|
|
|
|
|
|
|
// largest power of 2 that divides m10 + e10 is greater than e2. If e2 is less than e10, then |
|
206
|
|
|
|
|
|
|
// the result must be exact. Otherwise we use the existing multipleOfPowerOf2 function. |
|
207
|
0
|
0
|
|
|
|
|
trailingZeros = e2 < e10 || (e2 - e10 < 64 && multipleOfPowerOf2(m10, e2 - e10)); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
} else { |
|
209
|
0
|
|
|
|
|
|
e2 = floor_log2(m10) + e10 - ceil_log2pow5(-e10) - (DOUBLE_MANTISSA_BITS + 1); |
|
210
|
0
|
|
|
|
|
|
int j = e2 - e10 + ceil_log2pow5(-e10) - 1 + DOUBLE_POW5_INV_BITCOUNT; |
|
211
|
|
|
|
|
|
|
#if defined(RYU_OPTIMIZE_SIZE) |
|
212
|
|
|
|
|
|
|
uint64_t pow5[2]; |
|
213
|
|
|
|
|
|
|
double_computeInvPow5(-e10, pow5); |
|
214
|
|
|
|
|
|
|
m2 = mulShift64(m10, pow5, j); |
|
215
|
|
|
|
|
|
|
#else |
|
216
|
0
|
0
|
|
|
|
|
assert(-e10 < DOUBLE_POW5_INV_TABLE_SIZE); |
|
217
|
0
|
|
|
|
|
|
m2 = mulShift64(m10, DOUBLE_POW5_INV_SPLIT[-e10], j); |
|
218
|
|
|
|
|
|
|
#endif |
|
219
|
0
|
|
|
|
|
|
trailingZeros = multipleOfPowerOf5(m10, -e10); |
|
220
|
|
|
|
|
|
|
} |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
#ifdef RYU_DEBUG |
|
223
|
0
|
|
|
|
|
|
printf("m2 * 2^e2 = %" PRIu64 " * 2^%d\n", m2, e2); |
|
224
|
|
|
|
|
|
|
#endif |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
// Compute the final IEEE exponent. |
|
227
|
0
|
|
|
|
|
|
uint32_t ieee_e2 = (uint32_t) max32(0, e2 + DOUBLE_EXPONENT_BIAS + floor_log2(m2)); |
|
228
|
|
|
|
|
|
|
|
|
229
|
0
|
0
|
|
|
|
|
if (ieee_e2 > 0x7fe) { |
|
230
|
|
|
|
|
|
|
// Final IEEE exponent is larger than the maximum representable; return +/-Infinity. |
|
231
|
0
|
|
|
|
|
|
uint64_t ieee = (((uint64_t) signedM) << (DOUBLE_EXPONENT_BITS + DOUBLE_MANTISSA_BITS)) | (0x7ffull << DOUBLE_MANTISSA_BITS); |
|
232
|
0
|
|
|
|
|
|
*result = int64Bits2Double(ieee); |
|
233
|
0
|
|
|
|
|
|
return SUCCESS; |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
// We need to figure out how much we need to shift m2. The tricky part is that we need to take |
|
237
|
|
|
|
|
|
|
// the final IEEE exponent into account, so we need to reverse the bias and also special-case |
|
238
|
|
|
|
|
|
|
// the value 0. |
|
239
|
0
|
0
|
|
|
|
|
int32_t shift = (ieee_e2 == 0 ? 1 : ieee_e2) - e2 - DOUBLE_EXPONENT_BIAS - DOUBLE_MANTISSA_BITS; |
|
240
|
0
|
0
|
|
|
|
|
assert(shift >= 0); |
|
241
|
|
|
|
|
|
|
#ifdef RYU_DEBUG |
|
242
|
0
|
|
|
|
|
|
printf("ieee_e2 = %d\n", ieee_e2); |
|
243
|
0
|
|
|
|
|
|
printf("shift = %d\n", shift); |
|
244
|
|
|
|
|
|
|
#endif |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
// We need to round up if the exact value is more than 0.5 above the value we computed. That's |
|
247
|
|
|
|
|
|
|
// equivalent to checking if the last removed bit was 1 and either the value was not just |
|
248
|
|
|
|
|
|
|
// trailing zeros or the result would otherwise be odd. |
|
249
|
|
|
|
|
|
|
// |
|
250
|
|
|
|
|
|
|
// We need to update trailingZeros given that we have the exact output exponent ieee_e2 now. |
|
251
|
0
|
|
|
|
|
|
trailingZeros &= (m2 & ((1ull << (shift - 1)) - 1)) == 0; |
|
252
|
0
|
|
|
|
|
|
uint64_t lastRemovedBit = (m2 >> (shift - 1)) & 1; |
|
253
|
0
|
0
|
|
|
|
|
bool roundUp = (lastRemovedBit != 0) && (!trailingZeros || (((m2 >> shift) & 1) != 0)); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
#ifdef RYU_DEBUG |
|
256
|
0
|
|
|
|
|
|
printf("roundUp = %d\n", roundUp); |
|
257
|
0
|
|
|
|
|
|
printf("ieee_m2 = %" PRIu64 "\n", (m2 >> shift) + roundUp); |
|
258
|
|
|
|
|
|
|
#endif |
|
259
|
0
|
|
|
|
|
|
uint64_t ieee_m2 = (m2 >> shift) + roundUp; |
|
260
|
0
|
0
|
|
|
|
|
assert(ieee_m2 <= (1ull << (DOUBLE_MANTISSA_BITS + 1))); |
|
261
|
0
|
|
|
|
|
|
ieee_m2 &= (1ull << DOUBLE_MANTISSA_BITS) - 1; |
|
262
|
0
|
0
|
|
|
|
|
if (ieee_m2 == 0 && roundUp) { |
|
|
|
0
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
// Due to how the IEEE represents +/-Infinity, we don't need to check for overflow here. |
|
264
|
0
|
|
|
|
|
|
ieee_e2++; |
|
265
|
|
|
|
|
|
|
} |
|
266
|
|
|
|
|
|
|
|
|
267
|
0
|
|
|
|
|
|
uint64_t ieee = (((((uint64_t) signedM) << DOUBLE_EXPONENT_BITS) | (uint64_t)ieee_e2) << DOUBLE_MANTISSA_BITS) | ieee_m2; |
|
268
|
0
|
|
|
|
|
|
*result = int64Bits2Double(ieee); |
|
269
|
0
|
|
|
|
|
|
return SUCCESS; |
|
270
|
|
|
|
|
|
|
} |
|
271
|
|
|
|
|
|
|
|
|
272
|
0
|
|
|
|
|
|
enum Status s2d(const char * buffer, double * result) { |
|
273
|
0
|
|
|
|
|
|
return s2d_n(buffer, strlen(buffer), result); |
|
274
|
|
|
|
|
|
|
} |