File indexing completed on 2025-01-18 10:02:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #pragma once
0011
0012 #include <array> // array
0013 #include <cmath> // signbit, isfinite
0014 #include <cstdint> // intN_t, uintN_t
0015 #include <cstring> // memcpy, memmove
0016 #include <limits> // numeric_limits
0017 #include <type_traits> // conditional
0018
0019 #include <nlohmann/detail/macro_scope.hpp>
0020
0021 NLOHMANN_JSON_NAMESPACE_BEGIN
0022 namespace detail
0023 {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 namespace dtoa_impl
0045 {
0046
0047 template<typename Target, typename Source>
0048 Target reinterpret_bits(const Source source)
0049 {
0050 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
0051
0052 Target target;
0053 std::memcpy(&target, &source, sizeof(Source));
0054 return target;
0055 }
0056
0057 struct diyfp
0058 {
0059 static constexpr int kPrecision = 64;
0060
0061 std::uint64_t f = 0;
0062 int e = 0;
0063
0064 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
0065
0066
0067
0068
0069
0070 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
0071 {
0072 JSON_ASSERT(x.e == y.e);
0073 JSON_ASSERT(x.f >= y.f);
0074
0075 return {x.f - y.f, x.e};
0076 }
0077
0078
0079
0080
0081
0082 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
0083 {
0084 static_assert(kPrecision == 64, "internal error");
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
0110 const std::uint64_t u_hi = x.f >> 32u;
0111 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
0112 const std::uint64_t v_hi = y.f >> 32u;
0113
0114 const std::uint64_t p0 = u_lo * v_lo;
0115 const std::uint64_t p1 = u_lo * v_hi;
0116 const std::uint64_t p2 = u_hi * v_lo;
0117 const std::uint64_t p3 = u_hi * v_hi;
0118
0119 const std::uint64_t p0_hi = p0 >> 32u;
0120 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
0121 const std::uint64_t p1_hi = p1 >> 32u;
0122 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
0123 const std::uint64_t p2_hi = p2 >> 32u;
0124
0125 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 Q += std::uint64_t{1} << (64u - 32u - 1u);
0137
0138 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
0139
0140 return {h, x.e + y.e + 64};
0141 }
0142
0143
0144
0145
0146
0147 static diyfp normalize(diyfp x) noexcept
0148 {
0149 JSON_ASSERT(x.f != 0);
0150
0151 while ((x.f >> 63u) == 0)
0152 {
0153 x.f <<= 1u;
0154 x.e--;
0155 }
0156
0157 return x;
0158 }
0159
0160
0161
0162
0163
0164 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
0165 {
0166 const int delta = x.e - target_exponent;
0167
0168 JSON_ASSERT(delta >= 0);
0169 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
0170
0171 return {x.f << delta, target_exponent};
0172 }
0173 };
0174
0175 struct boundaries
0176 {
0177 diyfp w;
0178 diyfp minus;
0179 diyfp plus;
0180 };
0181
0182
0183
0184
0185
0186
0187
0188 template<typename FloatType>
0189 boundaries compute_boundaries(FloatType value)
0190 {
0191 JSON_ASSERT(std::isfinite(value));
0192 JSON_ASSERT(value > 0);
0193
0194
0195
0196
0197
0198
0199
0200
0201 static_assert(std::numeric_limits<FloatType>::is_iec559,
0202 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
0203
0204 constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
0205 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
0206 constexpr int kMinExp = 1 - kBias;
0207 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1);
0208
0209 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
0210
0211 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
0212 const std::uint64_t E = bits >> (kPrecision - 1);
0213 const std::uint64_t F = bits & (kHiddenBit - 1);
0214
0215 const bool is_denormal = E == 0;
0216 const diyfp v = is_denormal
0217 ? diyfp(F, kMinExp)
0218 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241 const bool lower_boundary_is_closer = F == 0 && E > 1;
0242 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
0243 const diyfp m_minus = lower_boundary_is_closer
0244 ? diyfp(4 * v.f - 1, v.e - 2)
0245 : diyfp(2 * v.f - 1, v.e - 1);
0246
0247
0248 const diyfp w_plus = diyfp::normalize(m_plus);
0249
0250
0251 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
0252
0253 return {diyfp::normalize(v), w_minus, w_plus};
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311 constexpr int kAlpha = -60;
0312 constexpr int kGamma = -32;
0313
0314 struct cached_power
0315 {
0316 std::uint64_t f;
0317 int e;
0318 int k;
0319 };
0320
0321
0322
0323
0324
0325
0326
0327
0328 inline cached_power get_cached_power_for_binary_exponent(int e)
0329 {
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 constexpr int kCachedPowersMinDecExp = -300;
0381 constexpr int kCachedPowersDecStep = 8;
0382
0383 static constexpr std::array<cached_power, 79> kCachedPowers =
0384 {
0385 {
0386 { 0xAB70FE17C79AC6CA, -1060, -300 },
0387 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
0388 { 0xBE5691EF416BD60C, -1007, -284 },
0389 { 0x8DD01FAD907FFC3C, -980, -276 },
0390 { 0xD3515C2831559A83, -954, -268 },
0391 { 0x9D71AC8FADA6C9B5, -927, -260 },
0392 { 0xEA9C227723EE8BCB, -901, -252 },
0393 { 0xAECC49914078536D, -874, -244 },
0394 { 0x823C12795DB6CE57, -847, -236 },
0395 { 0xC21094364DFB5637, -821, -228 },
0396 { 0x9096EA6F3848984F, -794, -220 },
0397 { 0xD77485CB25823AC7, -768, -212 },
0398 { 0xA086CFCD97BF97F4, -741, -204 },
0399 { 0xEF340A98172AACE5, -715, -196 },
0400 { 0xB23867FB2A35B28E, -688, -188 },
0401 { 0x84C8D4DFD2C63F3B, -661, -180 },
0402 { 0xC5DD44271AD3CDBA, -635, -172 },
0403 { 0x936B9FCEBB25C996, -608, -164 },
0404 { 0xDBAC6C247D62A584, -582, -156 },
0405 { 0xA3AB66580D5FDAF6, -555, -148 },
0406 { 0xF3E2F893DEC3F126, -529, -140 },
0407 { 0xB5B5ADA8AAFF80B8, -502, -132 },
0408 { 0x87625F056C7C4A8B, -475, -124 },
0409 { 0xC9BCFF6034C13053, -449, -116 },
0410 { 0x964E858C91BA2655, -422, -108 },
0411 { 0xDFF9772470297EBD, -396, -100 },
0412 { 0xA6DFBD9FB8E5B88F, -369, -92 },
0413 { 0xF8A95FCF88747D94, -343, -84 },
0414 { 0xB94470938FA89BCF, -316, -76 },
0415 { 0x8A08F0F8BF0F156B, -289, -68 },
0416 { 0xCDB02555653131B6, -263, -60 },
0417 { 0x993FE2C6D07B7FAC, -236, -52 },
0418 { 0xE45C10C42A2B3B06, -210, -44 },
0419 { 0xAA242499697392D3, -183, -36 },
0420 { 0xFD87B5F28300CA0E, -157, -28 },
0421 { 0xBCE5086492111AEB, -130, -20 },
0422 { 0x8CBCCC096F5088CC, -103, -12 },
0423 { 0xD1B71758E219652C, -77, -4 },
0424 { 0x9C40000000000000, -50, 4 },
0425 { 0xE8D4A51000000000, -24, 12 },
0426 { 0xAD78EBC5AC620000, 3, 20 },
0427 { 0x813F3978F8940984, 30, 28 },
0428 { 0xC097CE7BC90715B3, 56, 36 },
0429 { 0x8F7E32CE7BEA5C70, 83, 44 },
0430 { 0xD5D238A4ABE98068, 109, 52 },
0431 { 0x9F4F2726179A2245, 136, 60 },
0432 { 0xED63A231D4C4FB27, 162, 68 },
0433 { 0xB0DE65388CC8ADA8, 189, 76 },
0434 { 0x83C7088E1AAB65DB, 216, 84 },
0435 { 0xC45D1DF942711D9A, 242, 92 },
0436 { 0x924D692CA61BE758, 269, 100 },
0437 { 0xDA01EE641A708DEA, 295, 108 },
0438 { 0xA26DA3999AEF774A, 322, 116 },
0439 { 0xF209787BB47D6B85, 348, 124 },
0440 { 0xB454E4A179DD1877, 375, 132 },
0441 { 0x865B86925B9BC5C2, 402, 140 },
0442 { 0xC83553C5C8965D3D, 428, 148 },
0443 { 0x952AB45CFA97A0B3, 455, 156 },
0444 { 0xDE469FBD99A05FE3, 481, 164 },
0445 { 0xA59BC234DB398C25, 508, 172 },
0446 { 0xF6C69A72A3989F5C, 534, 180 },
0447 { 0xB7DCBF5354E9BECE, 561, 188 },
0448 { 0x88FCF317F22241E2, 588, 196 },
0449 { 0xCC20CE9BD35C78A5, 614, 204 },
0450 { 0x98165AF37B2153DF, 641, 212 },
0451 { 0xE2A0B5DC971F303A, 667, 220 },
0452 { 0xA8D9D1535CE3B396, 694, 228 },
0453 { 0xFB9B7CD9A4A7443C, 720, 236 },
0454 { 0xBB764C4CA7A44410, 747, 244 },
0455 { 0x8BAB8EEFB6409C1A, 774, 252 },
0456 { 0xD01FEF10A657842C, 800, 260 },
0457 { 0x9B10A4E5E9913129, 827, 268 },
0458 { 0xE7109BFBA19C0C9D, 853, 276 },
0459 { 0xAC2820D9623BF429, 880, 284 },
0460 { 0x80444B5E7AA7CF85, 907, 292 },
0461 { 0xBF21E44003ACDD2D, 933, 300 },
0462 { 0x8E679C2F5E44FF8F, 960, 308 },
0463 { 0xD433179D9C8CB841, 986, 316 },
0464 { 0x9E19DB92B4E31BA9, 1013, 324 },
0465 }
0466 };
0467
0468
0469
0470
0471
0472 JSON_ASSERT(e >= -1500);
0473 JSON_ASSERT(e <= 1500);
0474 const int f = kAlpha - e - 1;
0475 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
0476
0477 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
0478 JSON_ASSERT(index >= 0);
0479 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
0480
0481 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
0482 JSON_ASSERT(kAlpha <= cached.e + e + 64);
0483 JSON_ASSERT(kGamma >= cached.e + e + 64);
0484
0485 return cached;
0486 }
0487
0488
0489
0490
0491
0492 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
0493 {
0494
0495 if (n >= 1000000000)
0496 {
0497 pow10 = 1000000000;
0498 return 10;
0499 }
0500
0501 if (n >= 100000000)
0502 {
0503 pow10 = 100000000;
0504 return 9;
0505 }
0506 if (n >= 10000000)
0507 {
0508 pow10 = 10000000;
0509 return 8;
0510 }
0511 if (n >= 1000000)
0512 {
0513 pow10 = 1000000;
0514 return 7;
0515 }
0516 if (n >= 100000)
0517 {
0518 pow10 = 100000;
0519 return 6;
0520 }
0521 if (n >= 10000)
0522 {
0523 pow10 = 10000;
0524 return 5;
0525 }
0526 if (n >= 1000)
0527 {
0528 pow10 = 1000;
0529 return 4;
0530 }
0531 if (n >= 100)
0532 {
0533 pow10 = 100;
0534 return 3;
0535 }
0536 if (n >= 10)
0537 {
0538 pow10 = 10;
0539 return 2;
0540 }
0541
0542 pow10 = 1;
0543 return 1;
0544 }
0545
0546 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
0547 std::uint64_t rest, std::uint64_t ten_k)
0548 {
0549 JSON_ASSERT(len >= 1);
0550 JSON_ASSERT(dist <= delta);
0551 JSON_ASSERT(rest <= delta);
0552 JSON_ASSERT(ten_k > 0);
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573 while (rest < dist
0574 && delta - rest >= ten_k
0575 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
0576 {
0577 JSON_ASSERT(buf[len - 1] != '0');
0578 buf[len - 1]--;
0579 rest += ten_k;
0580 }
0581 }
0582
0583
0584
0585
0586
0587 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
0588 diyfp M_minus, diyfp w, diyfp M_plus)
0589 {
0590 static_assert(kAlpha >= -60, "internal error");
0591 static_assert(kGamma <= -32, "internal error");
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 JSON_ASSERT(M_plus.e >= kAlpha);
0606 JSON_ASSERT(M_plus.e <= kGamma);
0607
0608 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f;
0609 std::uint64_t dist = diyfp::sub(M_plus, w ).f;
0610
0611
0612
0613
0614
0615
0616
0617
0618 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
0619
0620 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e);
0621 std::uint64_t p2 = M_plus.f & (one.f - 1);
0622
0623
0624
0625
0626
0627 JSON_ASSERT(p1 > 0);
0628
0629 std::uint32_t pow10{};
0630 const int k = find_largest_pow10(p1, pow10);
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650 int n = k;
0651 while (n > 0)
0652 {
0653
0654
0655
0656
0657 const std::uint32_t d = p1 / pow10;
0658 const std::uint32_t r = p1 % pow10;
0659
0660
0661
0662
0663 JSON_ASSERT(d <= 9);
0664 buffer[length++] = static_cast<char>('0' + d);
0665
0666
0667
0668 p1 = r;
0669 n--;
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
0684 if (rest <= delta)
0685 {
0686
0687
0688 decimal_exponent += n;
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
0700 grisu2_round(buffer, length, dist, delta, rest, ten_n);
0701
0702 return;
0703 }
0704
0705 pow10 /= 10;
0706
0707
0708
0709 }
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750 JSON_ASSERT(p2 > delta);
0751
0752 int m = 0;
0753 for (;;)
0754 {
0755
0756
0757
0758
0759
0760
0761 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
0762 p2 *= 10;
0763 const std::uint64_t d = p2 >> -one.e;
0764 const std::uint64_t r = p2 & (one.f - 1);
0765
0766
0767
0768
0769
0770 JSON_ASSERT(d <= 9);
0771 buffer[length++] = static_cast<char>('0' + d);
0772
0773
0774
0775 p2 = r;
0776 m++;
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786 delta *= 10;
0787 dist *= 10;
0788 if (p2 <= delta)
0789 {
0790 break;
0791 }
0792 }
0793
0794
0795
0796 decimal_exponent -= m;
0797
0798
0799
0800
0801
0802
0803
0804 const std::uint64_t ten_m = one.f;
0805 grisu2_round(buffer, length, dist, delta, p2, ten_m);
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820 }
0821
0822
0823
0824
0825
0826
0827 JSON_HEDLEY_NON_NULL(1)
0828 inline void grisu2(char* buf, int& len, int& decimal_exponent,
0829 diyfp m_minus, diyfp v, diyfp m_plus)
0830 {
0831 JSON_ASSERT(m_plus.e == m_minus.e);
0832 JSON_ASSERT(m_plus.e == v.e);
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
0844
0845 const diyfp c_minus_k(cached.f, cached.e);
0846
0847
0848 const diyfp w = diyfp::mul(v, c_minus_k);
0849 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
0850 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873 const diyfp M_minus(w_minus.f + 1, w_minus.e);
0874 const diyfp M_plus (w_plus.f - 1, w_plus.e );
0875
0876 decimal_exponent = -cached.k;
0877
0878 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
0879 }
0880
0881
0882
0883
0884
0885
0886 template<typename FloatType>
0887 JSON_HEDLEY_NON_NULL(1)
0888 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
0889 {
0890 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
0891 "internal error: not enough precision");
0892
0893 JSON_ASSERT(std::isfinite(value));
0894 JSON_ASSERT(value > 0);
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912 #if 0
0913 const boundaries w = compute_boundaries(static_cast<double>(value));
0914 #else
0915 const boundaries w = compute_boundaries(value);
0916 #endif
0917
0918 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
0919 }
0920
0921
0922
0923
0924
0925
0926 JSON_HEDLEY_NON_NULL(1)
0927 JSON_HEDLEY_RETURNS_NON_NULL
0928 inline char* append_exponent(char* buf, int e)
0929 {
0930 JSON_ASSERT(e > -1000);
0931 JSON_ASSERT(e < 1000);
0932
0933 if (e < 0)
0934 {
0935 e = -e;
0936 *buf++ = '-';
0937 }
0938 else
0939 {
0940 *buf++ = '+';
0941 }
0942
0943 auto k = static_cast<std::uint32_t>(e);
0944 if (k < 10)
0945 {
0946
0947
0948 *buf++ = '0';
0949 *buf++ = static_cast<char>('0' + k);
0950 }
0951 else if (k < 100)
0952 {
0953 *buf++ = static_cast<char>('0' + k / 10);
0954 k %= 10;
0955 *buf++ = static_cast<char>('0' + k);
0956 }
0957 else
0958 {
0959 *buf++ = static_cast<char>('0' + k / 100);
0960 k %= 100;
0961 *buf++ = static_cast<char>('0' + k / 10);
0962 k %= 10;
0963 *buf++ = static_cast<char>('0' + k);
0964 }
0965
0966 return buf;
0967 }
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978 JSON_HEDLEY_NON_NULL(1)
0979 JSON_HEDLEY_RETURNS_NON_NULL
0980 inline char* format_buffer(char* buf, int len, int decimal_exponent,
0981 int min_exp, int max_exp)
0982 {
0983 JSON_ASSERT(min_exp < 0);
0984 JSON_ASSERT(max_exp > 0);
0985
0986 const int k = len;
0987 const int n = len + decimal_exponent;
0988
0989
0990
0991
0992
0993 if (k <= n && n <= max_exp)
0994 {
0995
0996
0997
0998 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
0999
1000 buf[n + 0] = '.';
1001 buf[n + 1] = '0';
1002 return buf + (static_cast<size_t>(n) + 2);
1003 }
1004
1005 if (0 < n && n <= max_exp)
1006 {
1007
1008
1009
1010 JSON_ASSERT(k > n);
1011
1012 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
1013 buf[n] = '.';
1014 return buf + (static_cast<size_t>(k) + 1U);
1015 }
1016
1017 if (min_exp < n && n <= 0)
1018 {
1019
1020
1021
1022 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
1023 buf[0] = '0';
1024 buf[1] = '.';
1025 std::memset(buf + 2, '0', static_cast<size_t>(-n));
1026 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
1027 }
1028
1029 if (k == 1)
1030 {
1031
1032
1033
1034 buf += 1;
1035 }
1036 else
1037 {
1038
1039
1040
1041 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
1042 buf[1] = '.';
1043 buf += 1 + static_cast<size_t>(k);
1044 }
1045
1046 *buf++ = 'e';
1047 return append_exponent(buf, n - 1);
1048 }
1049
1050 }
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062 template<typename FloatType>
1063 JSON_HEDLEY_NON_NULL(1, 2)
1064 JSON_HEDLEY_RETURNS_NON_NULL
1065 char* to_chars(char* first, const char* last, FloatType value)
1066 {
1067 static_cast<void>(last);
1068 JSON_ASSERT(std::isfinite(value));
1069
1070
1071 if (std::signbit(value))
1072 {
1073 value = -value;
1074 *first++ = '-';
1075 }
1076
1077 #ifdef __GNUC__
1078 #pragma GCC diagnostic push
1079 #pragma GCC diagnostic ignored "-Wfloat-equal"
1080 #endif
1081 if (value == 0)
1082 {
1083 *first++ = '0';
1084
1085 *first++ = '.';
1086 *first++ = '0';
1087 return first;
1088 }
1089 #ifdef __GNUC__
1090 #pragma GCC diagnostic pop
1091 #endif
1092
1093 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
1094
1095
1096
1097
1098
1099 int len = 0;
1100 int decimal_exponent = 0;
1101 dtoa_impl::grisu2(first, len, decimal_exponent, value);
1102
1103 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
1104
1105
1106 constexpr int kMinExp = -4;
1107
1108 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
1109
1110 JSON_ASSERT(last - first >= kMaxExp + 2);
1111 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
1112 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
1113
1114 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
1115 }
1116
1117 }
1118 NLOHMANN_JSON_NAMESPACE_END