6 #include "msinttypes/stdint.h" 12 #define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l)) 44 #if defined(_MSC_VER) && defined(_M_AMD64) 46 uint64_t l = _umul128(
f, rhs.
f, &h);
47 if (l & (uint64_t(1) << 63))
49 return DiyFp(h,
e + rhs.
e + 64);
50 #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) 51 unsigned __int128 p =
static_cast<unsigned __int128
>(
f) * static_cast<unsigned __int128>(rhs.
f);
53 uint64_t l =
static_cast<uint64_t
>(p);
54 if (l & (uint64_t(1) << 63))
56 return DiyFp(h,
e + rhs.
e + 64);
58 const uint64_t M32 = 0xFFFFFFFF;
59 const uint64_t a =
f >> 32;
60 const uint64_t b =
f & M32;
61 const uint64_t c = rhs.
f >> 32;
62 const uint64_t
d = rhs.
f & M32;
63 const uint64_t ac = a * c;
64 const uint64_t bc = b * c;
65 const uint64_t ad = a * d;
66 const uint64_t bd = b * d;
67 uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
69 return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32),
e + rhs.
e + 64);
74 #if defined(_MSC_VER) && defined(_M_AMD64) 76 _BitScanReverse64(&index,
f);
77 return DiyFp(
f << (63 - index),
e - (63 - index));
78 #elif defined(__GNUC__) 79 int s = __builtin_clzll(
f);
94 #if defined(_MSC_VER) && defined(_M_AMD64) 96 _BitScanReverse64(&index,
f);
97 return DiyFp (
f << (63 - index),
e - (63 - index));
111 DiyFp pl =
DiyFp((
f << 1) + 1,
e - 1).NormalizeBoundary();
113 mi.
f <<= mi.
e - pl.
e;
133 static const uint64_t kCachedPowers_F[] = {
179 static const int16_t kCachedPowers_E[] = {
180 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
181 -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
182 -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
183 -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
184 -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
185 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
186 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
187 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
188 907, 933, 960, 986, 1013, 1039, 1066
192 double dk = (-61 -
e) * 0.30102999566398114 + 347;
193 int k =
static_cast<int>(dk);
197 unsigned index =
static_cast<unsigned>((k >> 3) + 1);
198 *K = -(-348 +
static_cast<int>(index << 3));
200 assert(index <
sizeof(kCachedPowers_F) /
sizeof(kCachedPowers_F[0]));
201 return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
204 inline void GrisuRound(
char* buffer,
int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
205 while (rest < wp_w && delta - rest >= ten_kappa &&
206 (rest + ten_kappa < wp_w ||
207 wp_w - rest > rest + ten_kappa - wp_w)) {
215 if (n < 10)
return 1;
216 if (n < 100)
return 2;
217 if (n < 1000)
return 3;
218 if (n < 10000)
return 4;
219 if (n < 100000)
return 5;
220 if (n < 1000000)
return 6;
221 if (n < 10000000)
return 7;
222 if (n < 100000000)
return 8;
223 if (n < 1000000000)
return 9;
227 inline void DigitGen(
const DiyFp& W,
const DiyFp& Mp, uint64_t delta,
char* buffer,
int* len,
int* K) {
228 static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
229 const DiyFp one(uint64_t(1) << -Mp.
e, Mp.
e);
230 const DiyFp wp_w = Mp - W;
231 uint32_t p1 =
static_cast<uint32_t
>(Mp.
f >> -one.
e);
232 uint64_t p2 = Mp.
f & (one.
f - 1);
239 case 10: d = p1 / 1000000000; p1 %= 1000000000;
break;
240 case 9: d = p1 / 100000000; p1 %= 100000000;
break;
241 case 8: d = p1 / 10000000; p1 %= 10000000;
break;
242 case 7: d = p1 / 1000000; p1 %= 1000000;
break;
243 case 6: d = p1 / 100000; p1 %= 100000;
break;
244 case 5: d = p1 / 10000; p1 %= 10000;
break;
245 case 4: d = p1 / 1000; p1 %= 1000;
break;
246 case 3: d = p1 / 100; p1 %= 100;
break;
247 case 2: d = p1 / 10; p1 %= 10;
break;
248 case 1: d = p1; p1 = 0;
break;
250 #if defined(_MSC_VER) 252 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 253 __builtin_unreachable();
259 buffer[(*len)++] =
'0' +
static_cast<char>(d);
261 uint64_t tmp = (
static_cast<uint64_t
>(p1) << -one.
e) + p2;
264 GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.
e, wp_w.
f);
273 char d =
static_cast<char>(p2 >> -one.
e);
275 buffer[(*len)++] =
'0' + d;
280 GrisuRound(buffer, *len, delta, p2, one.
f, wp_w.
f * kPow10[-kappa]);
286 inline void Grisu2(
double value,
char* buffer,
int* length,
int* K) {
287 const DiyFp v(value);
293 DiyFp Wp = w_p * c_mk;
294 DiyFp Wm = w_m * c_mk;
297 DigitGen(W, Wp, Wp.
f - Wm.
f, buffer, length, K);
301 static const char cDigitsLut[200] = {
302 '0',
'0',
'0',
'1',
'0',
'2',
'0',
'3',
'0',
'4',
'0',
'5',
'0',
'6',
'0',
'7',
'0',
'8',
'0',
'9',
303 '1',
'0',
'1',
'1',
'1',
'2',
'1',
'3',
'1',
'4',
'1',
'5',
'1',
'6',
'1',
'7',
'1',
'8',
'1',
'9',
304 '2',
'0',
'2',
'1',
'2',
'2',
'2',
'3',
'2',
'4',
'2',
'5',
'2',
'6',
'2',
'7',
'2',
'8',
'2',
'9',
305 '3',
'0',
'3',
'1',
'3',
'2',
'3',
'3',
'3',
'4',
'3',
'5',
'3',
'6',
'3',
'7',
'3',
'8',
'3',
'9',
306 '4',
'0',
'4',
'1',
'4',
'2',
'4',
'3',
'4',
'4',
'4',
'5',
'4',
'6',
'4',
'7',
'4',
'8',
'4',
'9',
307 '5',
'0',
'5',
'1',
'5',
'2',
'5',
'3',
'5',
'4',
'5',
'5',
'5',
'6',
'5',
'7',
'5',
'8',
'5',
'9',
308 '6',
'0',
'6',
'1',
'6',
'2',
'6',
'3',
'6',
'4',
'6',
'5',
'6',
'6',
'6',
'7',
'6',
'8',
'6',
'9',
309 '7',
'0',
'7',
'1',
'7',
'2',
'7',
'3',
'7',
'4',
'7',
'5',
'7',
'6',
'7',
'7',
'7',
'8',
'7',
'9',
310 '8',
'0',
'8',
'1',
'8',
'2',
'8',
'3',
'8',
'4',
'8',
'5',
'8',
'6',
'8',
'7',
'8',
'8',
'8',
'9',
311 '9',
'0',
'9',
'1',
'9',
'2',
'9',
'3',
'9',
'4',
'9',
'5',
'9',
'6',
'9',
'7',
'9',
'8',
'9',
'9' 323 *buffer++ =
'0' +
static_cast<char>(K / 100);
335 *buffer++ =
'0' +
static_cast<char>(K);
340 inline void Prettify(
char* buffer,
int length,
int k) {
341 const int kk = length + k;
343 if (length <= kk && kk <= 21) {
345 for (
int i = length; i < kk; i++)
348 buffer[kk + 1] =
'0';
349 buffer[kk + 2] =
'\0';
351 else if (0 < kk && kk <= 21) {
353 memmove(&buffer[kk + 1], &buffer[kk], length - kk);
355 buffer[length + 1] =
'\0';
357 else if (-6 < kk && kk <= 0) {
359 const int offset = 2 - kk;
360 memmove(&buffer[offset], &buffer[0], length);
363 for (
int i = 2; i < offset; i++)
365 buffer[length + offset] =
'\0';
367 else if (length == 1) {
374 memmove(&buffer[2], &buffer[1], length - 1);
376 buffer[length + 1] =
'e';
383 assert(!isnan(value));
384 assert(!isinf(value));
399 Grisu2(value, buffer, &length, &K);
static const int kDpExponentBias
int dtoa_milo(double value, char *buffer)
static const int kDiySignificandSize
GeneratorWrapper< T > value(T &&value)
const char * GetDigitsLut()
void GrisuRound(char *buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w)
DiyFp operator*(const DiyFp &rhs) const
DiyFp operator-(const DiyFp &rhs) const
void Prettify(char *buffer, int length, int k)
static const uint64_t kDpSignificandMask
void Grisu2(double value, char *buffer, int *length, int *K)
DiyFp NormalizeBoundary() const
static const uint64_t kDpHiddenBit
void DigitGen(const DiyFp &W, const DiyFp &Mp, uint64_t delta, char *buffer, int *len, int *K)
unsigned CountDecimalDigit32(uint32_t n)
static const uint64_t kDpExponentMask
DiyFp GetCachedPower(int e, int *K)
static const int kDpSignificandSize
static const int kDpMinExponent
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
void WriteExponent(int K, char *buffer)
void NormalizedBoundaries(DiyFp *minus, DiyFp *plus) const