1 +
// Copyright 2020-2023 Junekey Jeon
 
2 +
// Copyright 2022 Peter Dimov
 
3 +
// Copyright 2023 Matt Borland
 
4 +
// Distributed under the Boost Software License, Version 1.0.
 
5 +
// https://www.boost.org/LICENSE_1_0.txt
 
6 +

 
7 +
#include <boost/json/detail/format.hpp>
 
8 +
#include <boost/json/detail/dragonbox/to_chars_integer_impl.hpp>
 
9 +
#include <limits>
 
10 +
#include <cstring>
 
11 +
#include <cstdio>
 
12 +
#include <cstdint>
 
13 +
#include <cmath>
 
14 +

 
15 +
namespace boost {
 
16 +
namespace json {
 
17 +
namespace detail {
 
18 +
namespace to_chars_detail {
 
19 +

 
20 +
#ifdef BOOST_MSVC
 
21 +
# pragma warning(push)
 
22 +
# pragma warning(disable: 4127) // Conditional expression is constant (e.g. BOOST_IF_CONSTEXPR statements)
 
23 +
#endif
 
24 +

 
25 +
    // These "//"'s are to prevent clang-format to ruin this nice alignment.
 
26 +
    // Thanks to reddit user u/mcmcc:
 
27 +
    // https://www.reddit.com/r/cpp/comments/so3wx9/dragonbox_110_is_released_a_fast_floattostring/hw8z26r/?context=3
 
28 +
    static constexpr char radix_100_head_table[] = {
 
29 +
        '0', '.', '1', '.', '2', '.', '3', '.', '4', '.', //
 
30 +
        '5', '.', '6', '.', '7', '.', '8', '.', '9', '.', //
 
31 +
        '1', '.', '1', '.', '1', '.', '1', '.', '1', '.', //
 
32 +
        '1', '.', '1', '.', '1', '.', '1', '.', '1', '.', //
 
33 +
        '2', '.', '2', '.', '2', '.', '2', '.', '2', '.', //
 
34 +
        '2', '.', '2', '.', '2', '.', '2', '.', '2', '.', //
 
35 +
        '3', '.', '3', '.', '3', '.', '3', '.', '3', '.', //
 
36 +
        '3', '.', '3', '.', '3', '.', '3', '.', '3', '.', //
 
37 +
        '4', '.', '4', '.', '4', '.', '4', '.', '4', '.', //
 
38 +
        '4', '.', '4', '.', '4', '.', '4', '.', '4', '.', //
 
39 +
        '5', '.', '5', '.', '5', '.', '5', '.', '5', '.', //
 
40 +
        '5', '.', '5', '.', '5', '.', '5', '.', '5', '.', //
 
41 +
        '6', '.', '6', '.', '6', '.', '6', '.', '6', '.', //
 
42 +
        '6', '.', '6', '.', '6', '.', '6', '.', '6', '.', //
 
43 +
        '7', '.', '7', '.', '7', '.', '7', '.', '7', '.', //
 
44 +
        '7', '.', '7', '.', '7', '.', '7', '.', '7', '.', //
 
45 +
        '8', '.', '8', '.', '8', '.', '8', '.', '8', '.', //
 
46 +
        '8', '.', '8', '.', '8', '.', '8', '.', '8', '.', //
 
47 +
        '9', '.', '9', '.', '9', '.', '9', '.', '9', '.', //
 
48 +
        '9', '.', '9', '.', '9', '.', '9', '.', '9', '.'  //
 
49 +
    };
 
50 +

 
51 +
    static void print_1_digit(std::uint32_t n, char* buffer) noexcept
 
52 +
    {
 
53 +
        *buffer = char('0' + n);
 
54 +
    }
 
55 +

 
56 +
    static void print_2_digits(std::uint32_t n, char* buffer) noexcept
 
57 +
    {
 
58 +
        std::memcpy(buffer, radix_table + n * 2, 2);
 
59 +
    }
 
60 +

 
61 +
    // These digit generation routines are inspired by James Anhalt's itoa algorithm:
 
62 +
    // https://github.com/jeaiii/itoa
 
63 +
    // The main idea is for given n, find y such that floor(10^k * y / 2^32) = n holds,
 
64 +
    // where k is an appropriate integer depending on the length of n.
 
65 +
    // For example, if n = 1234567, we set k = 6. In this case, we have
 
66 +
    // floor(y / 2^32) = 1,
 
67 +
    // floor(10^2 * ((10^0 * y) mod 2^32) / 2^32) = 23,
 
68 +
    // floor(10^2 * ((10^2 * y) mod 2^32) / 2^32) = 45, and
 
69 +
    // floor(10^2 * ((10^4 * y) mod 2^32) / 2^32) = 67.
 
70 +
    // See https://jk-jeon.github.io/posts/2022/02/jeaiii-algorithm/ for more explanation.
 
71 +

 
72 +
    BOOST_FORCEINLINE static void print_9_digits(std::uint32_t s32, int& exponent,
 
73 +
                                                char*& buffer) noexcept
 
74 +
    {
 
75 +
        // -- IEEE-754 binary32
 
76 +
        // Since we do not cut trailing zeros in advance, s32 must be of 6~9 digits
 
77 +
        // unless the original input was subnormal.
 
78 +
        // In particular, when it is of 9 digits it shouldn't have any trailing zeros.
 
79 +
        // -- IEEE-754 binary64
 
80 +
        // In this case, s32 must be of 7~9 digits unless the input is subnormal,
 
81 +
        // and it shouldn't have any trailing zeros if it is of 9 digits.
 
82 +
        if (s32 >= 100000000)
 
83 +
        {
 
84 +
            // 9 digits.
 
85 +
            // 1441151882 = ceil(2^57 / 1'0000'0000) + 1
 
86 +
            auto prod = s32 * std::uint64_t(1441151882);
 
87 +
            prod >>= 25;
 
88 +
            std::memcpy(buffer, radix_100_head_table + std::uint32_t(prod >> 32) * 2, 2);
 
89 +

 
90 +
            prod = std::uint32_t(prod) * std::uint64_t(100);
 
91 +
            print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
92 +
            prod = std::uint32_t(prod) * std::uint64_t(100);
 
93 +
            print_2_digits(std::uint32_t(prod >> 32), buffer + 4);
 
94 +
            prod = std::uint32_t(prod) * std::uint64_t(100);
 
95 +
            print_2_digits(std::uint32_t(prod >> 32), buffer + 6);
 
96 +
            prod = std::uint32_t(prod) * std::uint64_t(100);
 
97 +
            print_2_digits(std::uint32_t(prod >> 32), buffer + 8);
 
98 +

 
99 +
            exponent += 8;
 
100 +
            buffer += 10;
 
101 +
        }
 
102 +
        else if (s32 >= 1000000)
 
103 +
        {
 
104 +
            // 7 or 8 digits.
 
105 +
            // 281474978 = ceil(2^48 / 100'0000) + 1
 
106 +
            auto prod = s32 * std::uint64_t(281474978);
 
107 +
            prod >>= 16;
 
108 +
            const auto head_digits = std::uint32_t(prod >> 32);
 
109 +
            // If s32 is of 8 digits, increase the exponent by 7.
 
110 +
            // Otherwise, increase it by 6.
 
111 +
            exponent += static_cast<int>(6 + unsigned(head_digits >= 10));
 
112 +

 
113 +
            // Write the first digit and the decimal point.
 
114 +
            std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2);
 
115 +
            // This third character may be overwritten later, but we don't care.
 
116 +
            buffer[2] = radix_table[head_digits * 2 + 1];
 
117 +

 
118 +
            // Remaining 6 digits are all zero?
 
119 +
            if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 1000000))
 
120 +
            {
 
121 +
                // The number of characters actually need to be written is:
 
122 +
                //   1, if only the first digit is nonzero, which means that either s32 is of 7
 
123 +
                //   digits or it is of 8 digits but the second digit is zero, or
 
124 +
                //   3, otherwise.
 
125 +
                // Note that buffer[2] is never '0' if s32 is of 7 digits, because the input is
 
126 +
                // never zero.
 
127 +
                buffer += (1 + (unsigned(head_digits >= 10) & unsigned(buffer[2] > '0')) * 2);
 
128 +
            }
 
129 +
            else
 
130 +
            {
 
131 +
                // At least one of the remaining 6 digits are nonzero.
 
132 +
                // After this adjustment, now the first destination becomes buffer + 2.
 
133 +
                buffer += unsigned(head_digits >= 10);
 
134 +

 
135 +
                // Obtain the next two digits.
 
136 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
137 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
138 +

 
139 +
                // Remaining 4 digits are all zero?
 
140 +
                if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 10000))
 
141 +
                {
 
142 +
                    buffer += (3 + unsigned(buffer[3] > '0'));
 
143 +
                }
 
144 +
                else
 
145 +
                {
 
146 +
                    // At least one of the remaining 4 digits are nonzero.
 
147 +

 
148 +
                    // Obtain the next two digits.
 
149 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
150 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 4);
 
151 +

 
152 +
                    // Remaining 2 digits are all zero?
 
153 +
                    if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 100))
 
154 +
                    {
 
155 +
                        buffer += (5 + unsigned(buffer[5] > '0'));
 
156 +
                    }
 
157 +
                    else
 
158 +
                    {
 
159 +
                        // Obtain the last two digits.
 
160 +
                        prod = std::uint32_t(prod) * std::uint64_t(100);
 
161 +
                        print_2_digits(std::uint32_t(prod >> 32), buffer + 6);
 
162 +

 
163 +
                        buffer += (7 + unsigned(buffer[7] > '0'));
 
164 +
                    }
 
165 +
                }
 
166 +
            }
 
167 +
        }
 
168 +
        else if (s32 >= 10000)
 
169 +
        {
 
170 +
            // 5 or 6 digits.
 
171 +
            // 429497 = ceil(2^32 / 1'0000)
 
172 +
            auto prod = s32 * std::uint64_t(429497);
 
173 +
            const auto head_digits = std::uint32_t(prod >> 32);
 
174 +

 
175 +
            // If s32 is of 6 digits, increase the exponent by 5.
 
176 +
            // Otherwise, increase it by 4.
 
177 +
            exponent += static_cast<int>(4 + unsigned(head_digits >= 10));
 
178 +

 
179 +
            // Write the first digit and the decimal point.
 
180 +
            std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2);
 
181 +
            // This third character may be overwritten later but we don't care.
 
182 +
            buffer[2] = radix_table[head_digits * 2 + 1];
 
183 +

 
184 +
            // Remaining 4 digits are all zero?
 
185 +
            if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 10000))
 
186 +
            {
 
187 +
                // The number of characters actually written is 1 or 3, similarly to the case of
 
188 +
                // 7 or 8 digits.
 
189 +
                buffer += (1 + (unsigned(head_digits >= 10) & unsigned(buffer[2] > '0')) * 2);
 
190 +
            }
 
191 +
            else
 
192 +
            {
 
193 +
                // At least one of the remaining 4 digits are nonzero.
 
194 +
                // After this adjustment, now the first destination becomes buffer + 2.
 
195 +
                buffer += unsigned(head_digits >= 10);
 
196 +

 
197 +
                // Obtain the next two digits.
 
198 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
199 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
200 +

 
201 +
                // Remaining 2 digits are all zero?
 
202 +
                if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 100))
 
203 +
                {
 
204 +
                    buffer += (3 + unsigned(buffer[3] > '0'));
 
205 +
                }
 
206 +
                else
 
207 +
                {
 
208 +
                    // Obtain the last two digits.
 
209 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
210 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 4);
 
211 +

 
212 +
                    buffer += (5 + unsigned(buffer[5] > '0'));
 
213 +
                }
 
214 +
            }
 
215 +
        }
 
216 +
        else if (s32 >= 100)
 
217 +
        {
 
218 +
            // 3 or 4 digits.
 
219 +
            // 42949673 = ceil(2^32 / 100)
 
220 +
            auto prod = s32 * std::uint64_t(42949673);
 
221 +
            const auto head_digits = std::uint32_t(prod >> 32);
 
222 +

 
223 +
            // If s32 is of 4 digits, increase the exponent by 3.
 
224 +
            // Otherwise, increase it by 2.
 
225 +
            exponent += (2 + int(head_digits >= 10));
 
226 +

 
227 +
            // Write the first digit and the decimal point.
 
228 +
            std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2);
 
229 +
            // This third character may be overwritten later but we don't care.
 
230 +
            buffer[2] = radix_table[head_digits * 2 + 1];
 
231 +

 
232 +
            // Remaining 2 digits are all zero?
 
233 +
            if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 100))
 
234 +
            {
 
235 +
                // The number of characters actually written is 1 or 3, similarly to the case of
 
236 +
                // 7 or 8 digits.
 
237 +
                buffer += (1 + (unsigned(head_digits >= 10) & unsigned(buffer[2] > '0')) * 2);
 
238 +
            }
 
239 +
            else
 
240 +
            {
 
241 +
                // At least one of the remaining 2 digits are nonzero.
 
242 +
                // After this adjustment, now the first destination becomes buffer + 2.
 
243 +
                buffer += unsigned(head_digits >= 10);
 
244 +

 
245 +
                // Obtain the last two digits.
 
246 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
247 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
248 +

 
249 +
                buffer += (3 + unsigned(buffer[3] > '0'));
 
250 +
            }
 
251 +
        }
 
252 +
        else
 
253 +
        {
 
254 +
            // 1 or 2 digits.
 
255 +
            // If s32 is of 2 digits, increase the exponent by 1.
 
256 +
            exponent += int(s32 >= 10);
 
257 +

 
258 +
            // Write the first digit and the decimal point.
 
259 +
            std::memcpy(buffer, radix_100_head_table + s32 * 2, 2);
 
260 +
            // This third character may be overwritten later but we don't care.
 
261 +
            buffer[2] = radix_table[s32 * 2 + 1];
 
262 +

 
263 +
            // The number of characters actually written is 1 or 3, similarly to the case of
 
264 +
            // 7 or 8 digits.
 
265 +
            buffer += (1 + (unsigned(s32 >= 10) & unsigned(buffer[2] > '0')) * 2);
 
266 +
        }
 
267 +
    }
 
268 +

 
269 +
    std::size_t dragon_box_print_chars(const std::uint64_t significand, int exponent, char* first, char* last) noexcept
 
270 +
    {
 
271 +
        BOOST_ASSERT( detail::max_number_chars >= std::size_t(last - first) );
 
272 +

 
273 +
        auto buffer = first;
 
274 +
        // Print significand by decomposing it into a 9-digit block and a 8-digit block.
 
275 +
        std::uint32_t first_block;
 
276 +
        std::uint32_t second_block {};
 
277 +
        bool no_second_block;
 
278 +

 
279 +
        if (significand >= 100000000)
 
280 +
        {
 
281 +
            first_block = std::uint32_t(significand / 100000000);
 
282 +
            second_block = std::uint32_t(significand) - first_block * 100000000;
 
283 +
            exponent += 8;
 
284 +
            no_second_block = (second_block == 0);
 
285 +
        }
 
286 +
        else
 
287 +
        {
 
288 +
            first_block = std::uint32_t(significand);
 
289 +
            no_second_block = true;
 
290 +
        }
 
291 +

 
292 +
        if (no_second_block)
 
293 +
        {
 
294 +
            print_9_digits(first_block, exponent, buffer);
 
295 +
        }
 
296 +
        else
 
297 +
        {
 
298 +
            // We proceed similarly to print_9_digits(), but since we do not need to remove
 
299 +
            // trailing zeros, the procedure is a bit simpler.
 
300 +
            if (first_block >= 100000000)
 
301 +
            {
 
302 +
                // The input is of 17 digits, thus there should be no trailing zero at all.
 
303 +
                // The first block is of 9 digits.
 
304 +
                // 1441151882 = ceil(2^57 / 1'0000'0000) + 1
 
305 +
                auto prod = first_block * std::uint64_t(1441151882);
 
306 +
                prod >>= 25;
 
307 +
                std::memcpy(buffer, radix_100_head_table + std::uint32_t(prod >> 32) * 2, 2);
 
308 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
309 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
310 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
311 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 4);
 
312 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
313 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 6);
 
314 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
315 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 8);
 
316 +

 
317 +
                // The second block is of 8 digits.
 
318 +
                // 281474978 = ceil(2^48 / 100'0000) + 1
 
319 +
                prod = second_block * std::uint64_t(281474978);
 
320 +
                prod >>= 16;
 
321 +
                prod += 1;
 
322 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 10);
 
323 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
324 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 12);
 
325 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
326 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 14);
 
327 +
                prod = std::uint32_t(prod) * std::uint64_t(100);
 
328 +
                print_2_digits(std::uint32_t(prod >> 32), buffer + 16);
 
329 +

 
330 +
                exponent += 8;
 
331 +
                buffer += 18;
 
332 +
            }
 
333 +
            else
 
334 +
            {
 
335 +
                if (first_block >= 1000000)
 
336 +
                {
 
337 +
                    // 7 or 8 digits.
 
338 +
                    // 281474978 = ceil(2^48 / 100'0000) + 1
 
339 +
                    auto prod = first_block * std::uint64_t(281474978);
 
340 +
                    prod >>= 16;
 
341 +
                    const auto head_digits = std::uint32_t(prod >> 32);
 
342 +

 
343 +
                    std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2);
 
344 +
                    buffer[2] = radix_table[head_digits * 2 + 1];
 
345 +

 
346 +
                    exponent += static_cast<int>(6 + unsigned(head_digits >= 10));
 
347 +
                    buffer += unsigned(head_digits >= 10);
 
348 +

 
349 +
                    // Print remaining 6 digits.
 
350 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
351 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
352 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
353 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 4);
 
354 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
355 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 6);
 
356 +

 
357 +
                    buffer += 8;
 
358 +
                }
 
359 +
                else if (first_block >= 10000)
 
360 +
                {
 
361 +
                    // 5 or 6 digits.
 
362 +
                    // 429497 = ceil(2^32 / 1'0000)
 
363 +
                    auto prod = first_block * std::uint64_t(429497);
 
364 +
                    const auto head_digits = std::uint32_t(prod >> 32);
 
365 +

 
366 +
                    std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2);
 
367 +
                    buffer[2] = radix_table[head_digits * 2 + 1];
 
368 +

 
369 +
                    exponent += static_cast<int>(4 + unsigned(head_digits >= 10));
 
370 +
                    buffer += unsigned(head_digits >= 10);
 
371 +

 
372 +
                    // Print remaining 4 digits.
 
373 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
374 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
375 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
376 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 4);
 
377 +

 
378 +
                    buffer += 6;
 
379 +
                }
 
380 +
                else if (first_block >= 100)
 
381 +
                {
 
382 +
                    // 3 or 4 digits.
 
383 +
                    // 42949673 = ceil(2^32 / 100)
 
384 +
                    auto prod = first_block * std::uint64_t(42949673);
 
385 +
                    const auto head_digits = std::uint32_t(prod >> 32);
 
386 +

 
387 +
                    std::memcpy(buffer, radix_100_head_table + head_digits * 2, 2);
 
388 +
                    buffer[2] = radix_table[head_digits * 2 + 1];
 
389 +

 
390 +
                    exponent += static_cast<int>(2 + unsigned(head_digits >= 10));
 
391 +
                    buffer += unsigned(head_digits >= 10);
 
392 +

 
393 +
                    // Print remaining 2 digits.
 
394 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
395 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
396 +

 
397 +
                    buffer += 4;
 
398 +
                }
 
399 +
                else
 
400 +
                {
 
401 +
                    // 1 or 2 digits.
 
402 +
                    std::memcpy(buffer, radix_100_head_table + first_block * 2, 2);
 
403 +
                    buffer[2] = radix_table[first_block * 2 + 1];
 
404 +

 
405 +
                    exponent += (first_block >= 10);
 
406 +
                    buffer += (2 + unsigned(first_block >= 10));
 
407 +
                }
 
408 +

 
409 +
                // Next, print the second block.
 
410 +
                // The second block is of 8 digits, but we may have trailing zeros.
 
411 +
                // 281474978 = ceil(2^48 / 100'0000) + 1
 
412 +
                auto prod = second_block * std::uint64_t(281474978);
 
413 +
                prod >>= 16;
 
414 +
                prod += 1;
 
415 +
                print_2_digits(std::uint32_t(prod >> 32), buffer);
 
416 +

 
417 +
                // Remaining 6 digits are all zero?
 
418 +
                if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 1000000))
 
419 +
                {
 
420 +
                    buffer += (1 + unsigned(buffer[1] > '0'));
 
421 +
                }
 
422 +
                else
 
423 +
                {
 
424 +
                    // Obtain the next two digits.
 
425 +
                    prod = std::uint32_t(prod) * std::uint64_t(100);
 
426 +
                    print_2_digits(std::uint32_t(prod >> 32), buffer + 2);
 
427 +

 
428 +
                    // Remaining 4 digits are all zero?
 
429 +
                    if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 10000))
 
430 +
                    {
 
431 +
                        buffer += (3 + unsigned(buffer[3] > '0'));
 
432 +
                    }
 
433 +
                    else
 
434 +
                    {
 
435 +
                        // Obtain the next two digits.
 
436 +
                        prod = std::uint32_t(prod) * std::uint64_t(100);
 
437 +
                        print_2_digits(std::uint32_t(prod >> 32), buffer + 4);
 
438 +

 
439 +
                        // Remaining 2 digits are all zero?
 
440 +
                        if (std::uint32_t(prod) <= std::uint32_t((std::uint64_t(1) << 32) / 100))
 
441 +
                        {
 
442 +
                            buffer += (5 + unsigned(buffer[5] > '0'));
 
443 +
                        }
 
444 +
                        else
 
445 +
                        {
 
446 +
                            // Obtain the last two digits.
 
447 +
                            prod = std::uint32_t(prod) * std::uint64_t(100);
 
448 +
                            print_2_digits(std::uint32_t(prod >> 32), buffer + 6);
 
449 +
                            buffer += (7 + unsigned(buffer[7] > '0'));
 
450 +
                        }
 
451 +
                    }
 
452 +
                }
 
453 +
            }
 
454 +
        }
 
455 +
        if (exponent < 0)
 
456 +
        {
 
457 +
            std::memcpy(buffer, "E-", 2);
 
458 +
            buffer += 2;
 
459 +
            exponent = -exponent;
 
460 +
        }
 
461 +
        else if (exponent == 0)
 
462 +
        {
 
463 +
            std::memcpy(buffer, "E0", 2);
 
464 +
            return 2 + (buffer - first);
 
465 +
        }
 
466 +
        else
 
467 +
        {
 
468 +
            std::memcpy(buffer, "E+", 2);
 
469 +
            buffer += 2;
 
470 +
        }
 
471 +

 
472 +
        if (exponent >= 100)
 
473 +
        {
 
474 +
            // d1 = exponent / 10; d2 = exponent % 10;
 
475 +
            // 6554 = ceil(2^16 / 10)
 
476 +
            auto prod = std::uint32_t(exponent) * std::uint32_t(6554);
 
477 +
            auto d1 = prod >> 16;
 
478 +
            prod = std::uint16_t(prod) * std::uint32_t(5); // * 10
 
479 +
            auto d2 = prod >> 15;                          // >> 16
 
480 +
            print_2_digits(d1, buffer);
 
481 +
            print_1_digit(d2, buffer + 2);
 
482 +
            buffer += 3;
 
483 +
        }
 
484 +
        else
 
485 +
        {
 
486 +
            print_2_digits(static_cast<std::uint32_t>(exponent), buffer);
 
487 +
            buffer += 2;
 
488 +
        }
 
489 +

 
490 +
        return buffer - first;
 
491 +
    }
 
492 +

 
493 +
#ifdef BOOST_MSVC
 
494 +
# pragma warning(pop)
 
495 +
#endif
 
496 +

 
497 +
} // namespace to_chars_detail
 
498 +
} // namespace detail
 
499 +
} // namespace json
 
500 +
} // namespace boost