25 #ifndef RAPIDJSON_DTOA_ 26 #define RAPIDJSON_DTOA_ 31 #pragma intrinsic(_BitScanReverse64) 42 RAPIDJSON_DIAG_OFF(effc++)
48 DiyFp(uint64_t f,
int e) : f(f), e(e) {}
56 int biased_e =
static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize);
57 uint64_t significand = (u.u64 & kDpSignificandMask);
59 f = significand + kDpHiddenBit;
60 e = biased_e - kDpExponentBias;
64 e = kDpMinExponent + 1;
68 DiyFp operator-(
const DiyFp& rhs)
const {
69 return DiyFp(f - rhs.f, e);
72 DiyFp operator*(
const DiyFp& rhs)
const {
73 #if defined(_MSC_VER) && defined(_M_AMD64) 75 uint64_t l = _umul128(f, rhs.f, &h);
76 if (l & (uint64_t(1) << 63))
78 return DiyFp(h, e + rhs.e + 64);
79 #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) 80 unsigned __int128 p =
static_cast<unsigned __int128
>(f) * static_cast<unsigned __int128>(rhs.f);
81 uint64_t h =
static_cast<uint64_t
>(p >> 64);
82 uint64_t l =
static_cast<uint64_t
>(p);
83 if (l & (uint64_t(1) << 63))
85 return DiyFp(h, e + rhs.e + 64);
87 const uint64_t M32 = 0xFFFFFFFF;
88 const uint64_t a = f >> 32;
89 const uint64_t b = f & M32;
90 const uint64_t c = rhs.f >> 32;
91 const uint64_t d = rhs.f & M32;
92 const uint64_t ac = a * c;
93 const uint64_t bc = b * c;
94 const uint64_t ad = a * d;
95 const uint64_t bd = b * d;
96 uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
98 return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
102 DiyFp Normalize()
const {
103 #if defined(_MSC_VER) && defined(_M_AMD64) 105 _BitScanReverse64(&index, f);
106 return DiyFp(f << (63 - index), e - (63 - index));
107 #elif defined(__GNUC__) 108 int s = __builtin_clzll(f);
109 return DiyFp(f << s, e - s);
112 while (!(res.f & kDpHiddenBit)) {
116 res.f <<= (kDiySignificandSize - kDpSignificandSize - 1);
117 res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 1);
122 DiyFp NormalizeBoundary()
const {
123 #if defined(_MSC_VER) && defined(_M_AMD64) 125 _BitScanReverse64(&index, f);
126 return DiyFp (f << (63 - index), e - (63 - index));
129 while (!(res.f & (kDpHiddenBit << 1))) {
133 res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);
134 res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);
139 void NormalizedBoundaries(DiyFp* minus, DiyFp* plus)
const {
140 DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
141 DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
142 mi.f <<= mi.e - pl.e;
148 static const int kDiySignificandSize = 64;
149 static const int kDpSignificandSize = 52;
150 static const int kDpExponentBias = 0x3FF + kDpSignificandSize;
151 static const int kDpMinExponent = -kDpExponentBias;
160 inline DiyFp GetCachedPower(
int e,
int* K) {
162 static const uint64_t kCachedPowers_F[] = {
208 static const int16_t kCachedPowers_E[] = {
209 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
210 -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
211 -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
212 -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
213 -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
214 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
215 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
216 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
217 907, 933, 960, 986, 1013, 1039, 1066
221 double dk = (-61 - e) * 0.30102999566398114 + 347;
222 int k =
static_cast<int>(dk);
226 unsigned index =
static_cast<unsigned>((k >> 3) + 1);
227 *K = -(-348 +
static_cast<int>(index << 3));
229 return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
232 inline void GrisuRound(
char* buffer,
int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
233 while (rest < wp_w && delta - rest >= ten_kappa &&
234 (rest + ten_kappa < wp_w ||
235 wp_w - rest > rest + ten_kappa - wp_w)) {
241 inline unsigned CountDecimalDigit32(uint32_t n) {
243 if (n < 10)
return 1;
244 if (n < 100)
return 2;
245 if (n < 1000)
return 3;
246 if (n < 10000)
return 4;
247 if (n < 100000)
return 5;
248 if (n < 1000000)
return 6;
249 if (n < 10000000)
return 7;
250 if (n < 100000000)
return 8;
251 if (n < 1000000000)
return 9;
255 inline void DigitGen(
const DiyFp& W,
const DiyFp& Mp, uint64_t delta,
char* buffer,
int* len,
int* K) {
256 static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
257 const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
258 const DiyFp wp_w = Mp - W;
259 uint32_t p1 =
static_cast<uint32_t
>(Mp.f >> -one.e);
260 uint64_t p2 = Mp.f & (one.f - 1);
261 int kappa = CountDecimalDigit32(p1);
267 case 10: d = p1 / 1000000000; p1 %= 1000000000;
break;
268 case 9: d = p1 / 100000000; p1 %= 100000000;
break;
269 case 8: d = p1 / 10000000; p1 %= 10000000;
break;
270 case 7: d = p1 / 1000000; p1 %= 1000000;
break;
271 case 6: d = p1 / 100000; p1 %= 100000;
break;
272 case 5: d = p1 / 10000; p1 %= 10000;
break;
273 case 4: d = p1 / 1000; p1 %= 1000;
break;
274 case 3: d = p1 / 100; p1 %= 100;
break;
275 case 2: d = p1 / 10; p1 %= 10;
break;
276 case 1: d = p1; p1 = 0;
break;
278 #if defined(_MSC_VER) 280 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 281 __builtin_unreachable();
287 buffer[(*len)++] =
static_cast<char>(
'0' +
static_cast<char>(d));
289 uint64_t tmp = (
static_cast<uint64_t
>(p1) << -one.e) + p2;
292 GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
301 char d =
static_cast<char>(p2 >> -one.e);
303 buffer[(*len)++] =
static_cast<char>(
'0' + d);
308 GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
314 inline void Grisu2(
double value,
char* buffer,
int* length,
int* K) {
315 const DiyFp v(value);
317 v.NormalizedBoundaries(&w_m, &w_p);
319 const DiyFp c_mk = GetCachedPower(w_p.e, K);
320 const DiyFp W = v.Normalize() * c_mk;
321 DiyFp Wp = w_p * c_mk;
322 DiyFp Wm = w_m * c_mk;
325 DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
328 inline char* WriteExponent(
int K,
char* buffer) {
335 *buffer++ =
static_cast<char>(
'0' +
static_cast<char>(K / 100));
337 const char* d = GetDigitsLut() + K * 2;
342 const char* d = GetDigitsLut() + K * 2;
347 *buffer++ =
static_cast<char>(
'0' +
static_cast<char>(K));
352 inline char* Prettify(
char* buffer,
int length,
int k) {
353 const int kk = length + k;
355 if (length <= kk && kk <= 21) {
357 for (
int i = length; i < kk; i++)
360 buffer[kk + 1] =
'0';
361 return &buffer[kk + 2];
363 else if (0 < kk && kk <= 21) {
365 std::memmove(&buffer[kk + 1], &buffer[kk], length - kk);
367 return &buffer[length + 1];
369 else if (-6 < kk && kk <= 0) {
371 const int offset = 2 - kk;
372 std::memmove(&buffer[offset], &buffer[0], length);
375 for (
int i = 2; i < offset; i++)
377 return &buffer[length + offset];
379 else if (length == 1) {
382 return WriteExponent(kk - 1, &buffer[2]);
386 std::memmove(&buffer[2], &buffer[1], length - 1);
388 buffer[length + 1] =
'e';
389 return WriteExponent(kk - 1, &buffer[0 + length + 2]);
393 inline char* dtoa(
double value,
char* buffer) {
406 Grisu2(value, buffer, &length, &K);
407 return Prettify(buffer, length, K);
418 #endif // RAPIDJSON_DTOA_ #define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:186
main RapidJSON namespace
Definition: rapidjson.h:241