1c5f01b2fSopenharmony_ci//     __ _____ _____ _____
2c5f01b2fSopenharmony_ci//  __|  |   __|     |   | |  JSON for Modern C++
3c5f01b2fSopenharmony_ci// |  |  |__   |  |  | | | |  version 3.11.2
4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5c5f01b2fSopenharmony_ci//
6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
7c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT
9c5f01b2fSopenharmony_ci
10c5f01b2fSopenharmony_ci#pragma once
11c5f01b2fSopenharmony_ci
12c5f01b2fSopenharmony_ci#include <array> // array
13c5f01b2fSopenharmony_ci#include <cmath>   // signbit, isfinite
14c5f01b2fSopenharmony_ci#include <cstdint> // intN_t, uintN_t
15c5f01b2fSopenharmony_ci#include <cstring> // memcpy, memmove
16c5f01b2fSopenharmony_ci#include <limits> // numeric_limits
17c5f01b2fSopenharmony_ci#include <type_traits> // conditional
18c5f01b2fSopenharmony_ci
19c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_scope.hpp>
20c5f01b2fSopenharmony_ci
21c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_BEGIN
22c5f01b2fSopenharmony_cinamespace detail
23c5f01b2fSopenharmony_ci{
24c5f01b2fSopenharmony_ci
25c5f01b2fSopenharmony_ci/*!
26c5f01b2fSopenharmony_ci@brief implements the Grisu2 algorithm for binary to decimal floating-point
27c5f01b2fSopenharmony_ciconversion.
28c5f01b2fSopenharmony_ci
29c5f01b2fSopenharmony_ciThis implementation is a slightly modified version of the reference
30c5f01b2fSopenharmony_ciimplementation which may be obtained from
31c5f01b2fSopenharmony_cihttp://florian.loitsch.com/publications (bench.tar.gz).
32c5f01b2fSopenharmony_ci
33c5f01b2fSopenharmony_ciThe code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
34c5f01b2fSopenharmony_ci
35c5f01b2fSopenharmony_ciFor a detailed description of the algorithm see:
36c5f01b2fSopenharmony_ci
37c5f01b2fSopenharmony_ci[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
38c5f01b2fSopenharmony_ci    Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
39c5f01b2fSopenharmony_ci    Language Design and Implementation, PLDI 2010
40c5f01b2fSopenharmony_ci[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
41c5f01b2fSopenharmony_ci    Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
42c5f01b2fSopenharmony_ci    Design and Implementation, PLDI 1996
43c5f01b2fSopenharmony_ci*/
44c5f01b2fSopenharmony_cinamespace dtoa_impl
45c5f01b2fSopenharmony_ci{
46c5f01b2fSopenharmony_ci
47c5f01b2fSopenharmony_citemplate<typename Target, typename Source>
48c5f01b2fSopenharmony_ciTarget reinterpret_bits(const Source source)
49c5f01b2fSopenharmony_ci{
50c5f01b2fSopenharmony_ci    static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
51c5f01b2fSopenharmony_ci
52c5f01b2fSopenharmony_ci    Target target;
53c5f01b2fSopenharmony_ci    std::memcpy(&target, &source, sizeof(Source));
54c5f01b2fSopenharmony_ci    return target;
55c5f01b2fSopenharmony_ci}
56c5f01b2fSopenharmony_ci
57c5f01b2fSopenharmony_cistruct diyfp // f * 2^e
58c5f01b2fSopenharmony_ci{
59c5f01b2fSopenharmony_ci    static constexpr int kPrecision = 64; // = q
60c5f01b2fSopenharmony_ci
61c5f01b2fSopenharmony_ci    std::uint64_t f = 0;
62c5f01b2fSopenharmony_ci    int e = 0;
63c5f01b2fSopenharmony_ci
64c5f01b2fSopenharmony_ci    constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
65c5f01b2fSopenharmony_ci
66c5f01b2fSopenharmony_ci    /*!
67c5f01b2fSopenharmony_ci    @brief returns x - y
68c5f01b2fSopenharmony_ci    @pre x.e == y.e and x.f >= y.f
69c5f01b2fSopenharmony_ci    */
70c5f01b2fSopenharmony_ci    static diyfp sub(const diyfp& x, const diyfp& y) noexcept
71c5f01b2fSopenharmony_ci    {
72c5f01b2fSopenharmony_ci        JSON_ASSERT(x.e == y.e);
73c5f01b2fSopenharmony_ci        JSON_ASSERT(x.f >= y.f);
74c5f01b2fSopenharmony_ci
75c5f01b2fSopenharmony_ci        return {x.f - y.f, x.e};
76c5f01b2fSopenharmony_ci    }
77c5f01b2fSopenharmony_ci
78c5f01b2fSopenharmony_ci    /*!
79c5f01b2fSopenharmony_ci    @brief returns x * y
80c5f01b2fSopenharmony_ci    @note The result is rounded. (Only the upper q bits are returned.)
81c5f01b2fSopenharmony_ci    */
82c5f01b2fSopenharmony_ci    static diyfp mul(const diyfp& x, const diyfp& y) noexcept
83c5f01b2fSopenharmony_ci    {
84c5f01b2fSopenharmony_ci        static_assert(kPrecision == 64, "internal error");
85c5f01b2fSopenharmony_ci
86c5f01b2fSopenharmony_ci        // Computes:
87c5f01b2fSopenharmony_ci        //  f = round((x.f * y.f) / 2^q)
88c5f01b2fSopenharmony_ci        //  e = x.e + y.e + q
89c5f01b2fSopenharmony_ci
90c5f01b2fSopenharmony_ci        // Emulate the 64-bit * 64-bit multiplication:
91c5f01b2fSopenharmony_ci        //
92c5f01b2fSopenharmony_ci        // p = u * v
93c5f01b2fSopenharmony_ci        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
94c5f01b2fSopenharmony_ci        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
95c5f01b2fSopenharmony_ci        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
96c5f01b2fSopenharmony_ci        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
97c5f01b2fSopenharmony_ci        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
98c5f01b2fSopenharmony_ci        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
99c5f01b2fSopenharmony_ci        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
100c5f01b2fSopenharmony_ci        //
101c5f01b2fSopenharmony_ci        // (Since Q might be larger than 2^32 - 1)
102c5f01b2fSopenharmony_ci        //
103c5f01b2fSopenharmony_ci        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
104c5f01b2fSopenharmony_ci        //
105c5f01b2fSopenharmony_ci        // (Q_hi + H does not overflow a 64-bit int)
106c5f01b2fSopenharmony_ci        //
107c5f01b2fSopenharmony_ci        //   = p_lo + 2^64 p_hi
108c5f01b2fSopenharmony_ci
109c5f01b2fSopenharmony_ci        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
110c5f01b2fSopenharmony_ci        const std::uint64_t u_hi = x.f >> 32u;
111c5f01b2fSopenharmony_ci        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
112c5f01b2fSopenharmony_ci        const std::uint64_t v_hi = y.f >> 32u;
113c5f01b2fSopenharmony_ci
114c5f01b2fSopenharmony_ci        const std::uint64_t p0 = u_lo * v_lo;
115c5f01b2fSopenharmony_ci        const std::uint64_t p1 = u_lo * v_hi;
116c5f01b2fSopenharmony_ci        const std::uint64_t p2 = u_hi * v_lo;
117c5f01b2fSopenharmony_ci        const std::uint64_t p3 = u_hi * v_hi;
118c5f01b2fSopenharmony_ci
119c5f01b2fSopenharmony_ci        const std::uint64_t p0_hi = p0 >> 32u;
120c5f01b2fSopenharmony_ci        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
121c5f01b2fSopenharmony_ci        const std::uint64_t p1_hi = p1 >> 32u;
122c5f01b2fSopenharmony_ci        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
123c5f01b2fSopenharmony_ci        const std::uint64_t p2_hi = p2 >> 32u;
124c5f01b2fSopenharmony_ci
125c5f01b2fSopenharmony_ci        std::uint64_t Q = p0_hi + p1_lo + p2_lo;
126c5f01b2fSopenharmony_ci
127c5f01b2fSopenharmony_ci        // The full product might now be computed as
128c5f01b2fSopenharmony_ci        //
129c5f01b2fSopenharmony_ci        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
130c5f01b2fSopenharmony_ci        // p_lo = p0_lo + (Q << 32)
131c5f01b2fSopenharmony_ci        //
132c5f01b2fSopenharmony_ci        // But in this particular case here, the full p_lo is not required.
133c5f01b2fSopenharmony_ci        // Effectively we only need to add the highest bit in p_lo to p_hi (and
134c5f01b2fSopenharmony_ci        // Q_hi + 1 does not overflow).
135c5f01b2fSopenharmony_ci
136c5f01b2fSopenharmony_ci        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
137c5f01b2fSopenharmony_ci
138c5f01b2fSopenharmony_ci        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
139c5f01b2fSopenharmony_ci
140c5f01b2fSopenharmony_ci        return {h, x.e + y.e + 64};
141c5f01b2fSopenharmony_ci    }
142c5f01b2fSopenharmony_ci
143c5f01b2fSopenharmony_ci    /*!
144c5f01b2fSopenharmony_ci    @brief normalize x such that the significand is >= 2^(q-1)
145c5f01b2fSopenharmony_ci    @pre x.f != 0
146c5f01b2fSopenharmony_ci    */
147c5f01b2fSopenharmony_ci    static diyfp normalize(diyfp x) noexcept
148c5f01b2fSopenharmony_ci    {
149c5f01b2fSopenharmony_ci        JSON_ASSERT(x.f != 0);
150c5f01b2fSopenharmony_ci
151c5f01b2fSopenharmony_ci        while ((x.f >> 63u) == 0)
152c5f01b2fSopenharmony_ci        {
153c5f01b2fSopenharmony_ci            x.f <<= 1u;
154c5f01b2fSopenharmony_ci            x.e--;
155c5f01b2fSopenharmony_ci        }
156c5f01b2fSopenharmony_ci
157c5f01b2fSopenharmony_ci        return x;
158c5f01b2fSopenharmony_ci    }
159c5f01b2fSopenharmony_ci
160c5f01b2fSopenharmony_ci    /*!
161c5f01b2fSopenharmony_ci    @brief normalize x such that the result has the exponent E
162c5f01b2fSopenharmony_ci    @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
163c5f01b2fSopenharmony_ci    */
164c5f01b2fSopenharmony_ci    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
165c5f01b2fSopenharmony_ci    {
166c5f01b2fSopenharmony_ci        const int delta = x.e - target_exponent;
167c5f01b2fSopenharmony_ci
168c5f01b2fSopenharmony_ci        JSON_ASSERT(delta >= 0);
169c5f01b2fSopenharmony_ci        JSON_ASSERT(((x.f << delta) >> delta) == x.f);
170c5f01b2fSopenharmony_ci
171c5f01b2fSopenharmony_ci        return {x.f << delta, target_exponent};
172c5f01b2fSopenharmony_ci    }
173c5f01b2fSopenharmony_ci};
174c5f01b2fSopenharmony_ci
175c5f01b2fSopenharmony_cistruct boundaries
176c5f01b2fSopenharmony_ci{
177c5f01b2fSopenharmony_ci    diyfp w;
178c5f01b2fSopenharmony_ci    diyfp minus;
179c5f01b2fSopenharmony_ci    diyfp plus;
180c5f01b2fSopenharmony_ci};
181c5f01b2fSopenharmony_ci
182c5f01b2fSopenharmony_ci/*!
183c5f01b2fSopenharmony_ciCompute the (normalized) diyfp representing the input number 'value' and its
184c5f01b2fSopenharmony_ciboundaries.
185c5f01b2fSopenharmony_ci
186c5f01b2fSopenharmony_ci@pre value must be finite and positive
187c5f01b2fSopenharmony_ci*/
188c5f01b2fSopenharmony_citemplate<typename FloatType>
189c5f01b2fSopenharmony_ciboundaries compute_boundaries(FloatType value)
190c5f01b2fSopenharmony_ci{
191c5f01b2fSopenharmony_ci    JSON_ASSERT(std::isfinite(value));
192c5f01b2fSopenharmony_ci    JSON_ASSERT(value > 0);
193c5f01b2fSopenharmony_ci
194c5f01b2fSopenharmony_ci    // Convert the IEEE representation into a diyfp.
195c5f01b2fSopenharmony_ci    //
196c5f01b2fSopenharmony_ci    // If v is denormal:
197c5f01b2fSopenharmony_ci    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
198c5f01b2fSopenharmony_ci    // If v is normalized:
199c5f01b2fSopenharmony_ci    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
200c5f01b2fSopenharmony_ci
201c5f01b2fSopenharmony_ci    static_assert(std::numeric_limits<FloatType>::is_iec559,
202c5f01b2fSopenharmony_ci                  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
203c5f01b2fSopenharmony_ci
204c5f01b2fSopenharmony_ci    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
205c5f01b2fSopenharmony_ci    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
206c5f01b2fSopenharmony_ci    constexpr int      kMinExp    = 1 - kBias;
207c5f01b2fSopenharmony_ci    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
208c5f01b2fSopenharmony_ci
209c5f01b2fSopenharmony_ci    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
210c5f01b2fSopenharmony_ci
211c5f01b2fSopenharmony_ci    const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
212c5f01b2fSopenharmony_ci    const std::uint64_t E = bits >> (kPrecision - 1);
213c5f01b2fSopenharmony_ci    const std::uint64_t F = bits & (kHiddenBit - 1);
214c5f01b2fSopenharmony_ci
215c5f01b2fSopenharmony_ci    const bool is_denormal = E == 0;
216c5f01b2fSopenharmony_ci    const diyfp v = is_denormal
217c5f01b2fSopenharmony_ci                    ? diyfp(F, kMinExp)
218c5f01b2fSopenharmony_ci                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
219c5f01b2fSopenharmony_ci
220c5f01b2fSopenharmony_ci    // Compute the boundaries m- and m+ of the floating-point value
221c5f01b2fSopenharmony_ci    // v = f * 2^e.
222c5f01b2fSopenharmony_ci    //
223c5f01b2fSopenharmony_ci    // Determine v- and v+, the floating-point predecessor and successor if v,
224c5f01b2fSopenharmony_ci    // respectively.
225c5f01b2fSopenharmony_ci    //
226c5f01b2fSopenharmony_ci    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
227c5f01b2fSopenharmony_ci    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
228c5f01b2fSopenharmony_ci    //
229c5f01b2fSopenharmony_ci    //      v+ = v + 2^e
230c5f01b2fSopenharmony_ci    //
231c5f01b2fSopenharmony_ci    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
232c5f01b2fSopenharmony_ci    // between m- and m+ round to v, regardless of how the input rounding
233c5f01b2fSopenharmony_ci    // algorithm breaks ties.
234c5f01b2fSopenharmony_ci    //
235c5f01b2fSopenharmony_ci    //      ---+-------------+-------------+-------------+-------------+---  (A)
236c5f01b2fSopenharmony_ci    //         v-            m-            v             m+            v+
237c5f01b2fSopenharmony_ci    //
238c5f01b2fSopenharmony_ci    //      -----------------+------+------+-------------+-------------+---  (B)
239c5f01b2fSopenharmony_ci    //                       v-     m-     v             m+            v+
240c5f01b2fSopenharmony_ci
241c5f01b2fSopenharmony_ci    const bool lower_boundary_is_closer = F == 0 && E > 1;
242c5f01b2fSopenharmony_ci    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
243c5f01b2fSopenharmony_ci    const diyfp m_minus = lower_boundary_is_closer
244c5f01b2fSopenharmony_ci                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
245c5f01b2fSopenharmony_ci                          : diyfp(2 * v.f - 1, v.e - 1); // (A)
246c5f01b2fSopenharmony_ci
247c5f01b2fSopenharmony_ci    // Determine the normalized w+ = m+.
248c5f01b2fSopenharmony_ci    const diyfp w_plus = diyfp::normalize(m_plus);
249c5f01b2fSopenharmony_ci
250c5f01b2fSopenharmony_ci    // Determine w- = m- such that e_(w-) = e_(w+).
251c5f01b2fSopenharmony_ci    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
252c5f01b2fSopenharmony_ci
253c5f01b2fSopenharmony_ci    return {diyfp::normalize(v), w_minus, w_plus};
254c5f01b2fSopenharmony_ci}
255c5f01b2fSopenharmony_ci
256c5f01b2fSopenharmony_ci// Given normalized diyfp w, Grisu needs to find a (normalized) cached
257c5f01b2fSopenharmony_ci// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
258c5f01b2fSopenharmony_ci// within a certain range [alpha, gamma] (Definition 3.2 from [1])
259c5f01b2fSopenharmony_ci//
260c5f01b2fSopenharmony_ci//      alpha <= e = e_c + e_w + q <= gamma
261c5f01b2fSopenharmony_ci//
262c5f01b2fSopenharmony_ci// or
263c5f01b2fSopenharmony_ci//
264c5f01b2fSopenharmony_ci//      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
265c5f01b2fSopenharmony_ci//                          <= f_c * f_w * 2^gamma
266c5f01b2fSopenharmony_ci//
267c5f01b2fSopenharmony_ci// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
268c5f01b2fSopenharmony_ci//
269c5f01b2fSopenharmony_ci//      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
270c5f01b2fSopenharmony_ci//
271c5f01b2fSopenharmony_ci// or
272c5f01b2fSopenharmony_ci//
273c5f01b2fSopenharmony_ci//      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
274c5f01b2fSopenharmony_ci//
275c5f01b2fSopenharmony_ci// The choice of (alpha,gamma) determines the size of the table and the form of
276c5f01b2fSopenharmony_ci// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
277c5f01b2fSopenharmony_ci// in practice:
278c5f01b2fSopenharmony_ci//
279c5f01b2fSopenharmony_ci// The idea is to cut the number c * w = f * 2^e into two parts, which can be
280c5f01b2fSopenharmony_ci// processed independently: An integral part p1, and a fractional part p2:
281c5f01b2fSopenharmony_ci//
282c5f01b2fSopenharmony_ci//      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
283c5f01b2fSopenharmony_ci//              = (f div 2^-e) + (f mod 2^-e) * 2^e
284c5f01b2fSopenharmony_ci//              = p1 + p2 * 2^e
285c5f01b2fSopenharmony_ci//
286c5f01b2fSopenharmony_ci// The conversion of p1 into decimal form requires a series of divisions and
287c5f01b2fSopenharmony_ci// modulos by (a power of) 10. These operations are faster for 32-bit than for
288c5f01b2fSopenharmony_ci// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
289c5f01b2fSopenharmony_ci// achieved by choosing
290c5f01b2fSopenharmony_ci//
291c5f01b2fSopenharmony_ci//      -e >= 32   or   e <= -32 := gamma
292c5f01b2fSopenharmony_ci//
293c5f01b2fSopenharmony_ci// In order to convert the fractional part
294c5f01b2fSopenharmony_ci//
295c5f01b2fSopenharmony_ci//      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
296c5f01b2fSopenharmony_ci//
297c5f01b2fSopenharmony_ci// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
298c5f01b2fSopenharmony_ci// d[-i] are extracted in order:
299c5f01b2fSopenharmony_ci//
300c5f01b2fSopenharmony_ci//      (10 * p2) div 2^-e = d[-1]
301c5f01b2fSopenharmony_ci//      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
302c5f01b2fSopenharmony_ci//
303c5f01b2fSopenharmony_ci// The multiplication by 10 must not overflow. It is sufficient to choose
304c5f01b2fSopenharmony_ci//
305c5f01b2fSopenharmony_ci//      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
306c5f01b2fSopenharmony_ci//
307c5f01b2fSopenharmony_ci// Since p2 = f mod 2^-e < 2^-e,
308c5f01b2fSopenharmony_ci//
309c5f01b2fSopenharmony_ci//      -e <= 60   or   e >= -60 := alpha
310c5f01b2fSopenharmony_ci
311c5f01b2fSopenharmony_ciconstexpr int kAlpha = -60;
312c5f01b2fSopenharmony_ciconstexpr int kGamma = -32;
313c5f01b2fSopenharmony_ci
314c5f01b2fSopenharmony_cistruct cached_power // c = f * 2^e ~= 10^k
315c5f01b2fSopenharmony_ci{
316c5f01b2fSopenharmony_ci    std::uint64_t f;
317c5f01b2fSopenharmony_ci    int e;
318c5f01b2fSopenharmony_ci    int k;
319c5f01b2fSopenharmony_ci};
320c5f01b2fSopenharmony_ci
321c5f01b2fSopenharmony_ci/*!
322c5f01b2fSopenharmony_ciFor a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
323c5f01b2fSopenharmony_cipower-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
324c5f01b2fSopenharmony_cisatisfies (Definition 3.2 from [1])
325c5f01b2fSopenharmony_ci
326c5f01b2fSopenharmony_ci     alpha <= e_c + e + q <= gamma.
327c5f01b2fSopenharmony_ci*/
328c5f01b2fSopenharmony_ciinline cached_power get_cached_power_for_binary_exponent(int e)
329c5f01b2fSopenharmony_ci{
330c5f01b2fSopenharmony_ci    // Now
331c5f01b2fSopenharmony_ci    //
332c5f01b2fSopenharmony_ci    //      alpha <= e_c + e + q <= gamma                                    (1)
333c5f01b2fSopenharmony_ci    //      ==> f_c * 2^alpha <= c * 2^e * 2^q
334c5f01b2fSopenharmony_ci    //
335c5f01b2fSopenharmony_ci    // and since the c's are normalized, 2^(q-1) <= f_c,
336c5f01b2fSopenharmony_ci    //
337c5f01b2fSopenharmony_ci    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
338c5f01b2fSopenharmony_ci    //      ==> 2^(alpha - e - 1) <= c
339c5f01b2fSopenharmony_ci    //
340c5f01b2fSopenharmony_ci    // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
341c5f01b2fSopenharmony_ci    //
342c5f01b2fSopenharmony_ci    //      k = ceil( log_10( 2^(alpha - e - 1) ) )
343c5f01b2fSopenharmony_ci    //        = ceil( (alpha - e - 1) * log_10(2) )
344c5f01b2fSopenharmony_ci    //
345c5f01b2fSopenharmony_ci    // From the paper:
346c5f01b2fSopenharmony_ci    // "In theory the result of the procedure could be wrong since c is rounded,
347c5f01b2fSopenharmony_ci    //  and the computation itself is approximated [...]. In practice, however,
348c5f01b2fSopenharmony_ci    //  this simple function is sufficient."
349c5f01b2fSopenharmony_ci    //
350c5f01b2fSopenharmony_ci    // For IEEE double precision floating-point numbers converted into
351c5f01b2fSopenharmony_ci    // normalized diyfp's w = f * 2^e, with q = 64,
352c5f01b2fSopenharmony_ci    //
353c5f01b2fSopenharmony_ci    //      e >= -1022      (min IEEE exponent)
354c5f01b2fSopenharmony_ci    //           -52        (p - 1)
355c5f01b2fSopenharmony_ci    //           -52        (p - 1, possibly normalize denormal IEEE numbers)
356c5f01b2fSopenharmony_ci    //           -11        (normalize the diyfp)
357c5f01b2fSopenharmony_ci    //         = -1137
358c5f01b2fSopenharmony_ci    //
359c5f01b2fSopenharmony_ci    // and
360c5f01b2fSopenharmony_ci    //
361c5f01b2fSopenharmony_ci    //      e <= +1023      (max IEEE exponent)
362c5f01b2fSopenharmony_ci    //           -52        (p - 1)
363c5f01b2fSopenharmony_ci    //           -11        (normalize the diyfp)
364c5f01b2fSopenharmony_ci    //         = 960
365c5f01b2fSopenharmony_ci    //
366c5f01b2fSopenharmony_ci    // This binary exponent range [-1137,960] results in a decimal exponent
367c5f01b2fSopenharmony_ci    // range [-307,324]. One does not need to store a cached power for each
368c5f01b2fSopenharmony_ci    // k in this range. For each such k it suffices to find a cached power
369c5f01b2fSopenharmony_ci    // such that the exponent of the product lies in [alpha,gamma].
370c5f01b2fSopenharmony_ci    // This implies that the difference of the decimal exponents of adjacent
371c5f01b2fSopenharmony_ci    // table entries must be less than or equal to
372c5f01b2fSopenharmony_ci    //
373c5f01b2fSopenharmony_ci    //      floor( (gamma - alpha) * log_10(2) ) = 8.
374c5f01b2fSopenharmony_ci    //
375c5f01b2fSopenharmony_ci    // (A smaller distance gamma-alpha would require a larger table.)
376c5f01b2fSopenharmony_ci
377c5f01b2fSopenharmony_ci    // NB:
378c5f01b2fSopenharmony_ci    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
379c5f01b2fSopenharmony_ci
380c5f01b2fSopenharmony_ci    constexpr int kCachedPowersMinDecExp = -300;
381c5f01b2fSopenharmony_ci    constexpr int kCachedPowersDecStep = 8;
382c5f01b2fSopenharmony_ci
383c5f01b2fSopenharmony_ci    static constexpr std::array<cached_power, 79> kCachedPowers =
384c5f01b2fSopenharmony_ci    {
385c5f01b2fSopenharmony_ci        {
386c5f01b2fSopenharmony_ci            { 0xAB70FE17C79AC6CA, -1060, -300 },
387c5f01b2fSopenharmony_ci            { 0xFF77B1FCBEBCDC4F, -1034, -292 },
388c5f01b2fSopenharmony_ci            { 0xBE5691EF416BD60C, -1007, -284 },
389c5f01b2fSopenharmony_ci            { 0x8DD01FAD907FFC3C,  -980, -276 },
390c5f01b2fSopenharmony_ci            { 0xD3515C2831559A83,  -954, -268 },
391c5f01b2fSopenharmony_ci            { 0x9D71AC8FADA6C9B5,  -927, -260 },
392c5f01b2fSopenharmony_ci            { 0xEA9C227723EE8BCB,  -901, -252 },
393c5f01b2fSopenharmony_ci            { 0xAECC49914078536D,  -874, -244 },
394c5f01b2fSopenharmony_ci            { 0x823C12795DB6CE57,  -847, -236 },
395c5f01b2fSopenharmony_ci            { 0xC21094364DFB5637,  -821, -228 },
396c5f01b2fSopenharmony_ci            { 0x9096EA6F3848984F,  -794, -220 },
397c5f01b2fSopenharmony_ci            { 0xD77485CB25823AC7,  -768, -212 },
398c5f01b2fSopenharmony_ci            { 0xA086CFCD97BF97F4,  -741, -204 },
399c5f01b2fSopenharmony_ci            { 0xEF340A98172AACE5,  -715, -196 },
400c5f01b2fSopenharmony_ci            { 0xB23867FB2A35B28E,  -688, -188 },
401c5f01b2fSopenharmony_ci            { 0x84C8D4DFD2C63F3B,  -661, -180 },
402c5f01b2fSopenharmony_ci            { 0xC5DD44271AD3CDBA,  -635, -172 },
403c5f01b2fSopenharmony_ci            { 0x936B9FCEBB25C996,  -608, -164 },
404c5f01b2fSopenharmony_ci            { 0xDBAC6C247D62A584,  -582, -156 },
405c5f01b2fSopenharmony_ci            { 0xA3AB66580D5FDAF6,  -555, -148 },
406c5f01b2fSopenharmony_ci            { 0xF3E2F893DEC3F126,  -529, -140 },
407c5f01b2fSopenharmony_ci            { 0xB5B5ADA8AAFF80B8,  -502, -132 },
408c5f01b2fSopenharmony_ci            { 0x87625F056C7C4A8B,  -475, -124 },
409c5f01b2fSopenharmony_ci            { 0xC9BCFF6034C13053,  -449, -116 },
410c5f01b2fSopenharmony_ci            { 0x964E858C91BA2655,  -422, -108 },
411c5f01b2fSopenharmony_ci            { 0xDFF9772470297EBD,  -396, -100 },
412c5f01b2fSopenharmony_ci            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
413c5f01b2fSopenharmony_ci            { 0xF8A95FCF88747D94,  -343,  -84 },
414c5f01b2fSopenharmony_ci            { 0xB94470938FA89BCF,  -316,  -76 },
415c5f01b2fSopenharmony_ci            { 0x8A08F0F8BF0F156B,  -289,  -68 },
416c5f01b2fSopenharmony_ci            { 0xCDB02555653131B6,  -263,  -60 },
417c5f01b2fSopenharmony_ci            { 0x993FE2C6D07B7FAC,  -236,  -52 },
418c5f01b2fSopenharmony_ci            { 0xE45C10C42A2B3B06,  -210,  -44 },
419c5f01b2fSopenharmony_ci            { 0xAA242499697392D3,  -183,  -36 },
420c5f01b2fSopenharmony_ci            { 0xFD87B5F28300CA0E,  -157,  -28 },
421c5f01b2fSopenharmony_ci            { 0xBCE5086492111AEB,  -130,  -20 },
422c5f01b2fSopenharmony_ci            { 0x8CBCCC096F5088CC,  -103,  -12 },
423c5f01b2fSopenharmony_ci            { 0xD1B71758E219652C,   -77,   -4 },
424c5f01b2fSopenharmony_ci            { 0x9C40000000000000,   -50,    4 },
425c5f01b2fSopenharmony_ci            { 0xE8D4A51000000000,   -24,   12 },
426c5f01b2fSopenharmony_ci            { 0xAD78EBC5AC620000,     3,   20 },
427c5f01b2fSopenharmony_ci            { 0x813F3978F8940984,    30,   28 },
428c5f01b2fSopenharmony_ci            { 0xC097CE7BC90715B3,    56,   36 },
429c5f01b2fSopenharmony_ci            { 0x8F7E32CE7BEA5C70,    83,   44 },
430c5f01b2fSopenharmony_ci            { 0xD5D238A4ABE98068,   109,   52 },
431c5f01b2fSopenharmony_ci            { 0x9F4F2726179A2245,   136,   60 },
432c5f01b2fSopenharmony_ci            { 0xED63A231D4C4FB27,   162,   68 },
433c5f01b2fSopenharmony_ci            { 0xB0DE65388CC8ADA8,   189,   76 },
434c5f01b2fSopenharmony_ci            { 0x83C7088E1AAB65DB,   216,   84 },
435c5f01b2fSopenharmony_ci            { 0xC45D1DF942711D9A,   242,   92 },
436c5f01b2fSopenharmony_ci            { 0x924D692CA61BE758,   269,  100 },
437c5f01b2fSopenharmony_ci            { 0xDA01EE641A708DEA,   295,  108 },
438c5f01b2fSopenharmony_ci            { 0xA26DA3999AEF774A,   322,  116 },
439c5f01b2fSopenharmony_ci            { 0xF209787BB47D6B85,   348,  124 },
440c5f01b2fSopenharmony_ci            { 0xB454E4A179DD1877,   375,  132 },
441c5f01b2fSopenharmony_ci            { 0x865B86925B9BC5C2,   402,  140 },
442c5f01b2fSopenharmony_ci            { 0xC83553C5C8965D3D,   428,  148 },
443c5f01b2fSopenharmony_ci            { 0x952AB45CFA97A0B3,   455,  156 },
444c5f01b2fSopenharmony_ci            { 0xDE469FBD99A05FE3,   481,  164 },
445c5f01b2fSopenharmony_ci            { 0xA59BC234DB398C25,   508,  172 },
446c5f01b2fSopenharmony_ci            { 0xF6C69A72A3989F5C,   534,  180 },
447c5f01b2fSopenharmony_ci            { 0xB7DCBF5354E9BECE,   561,  188 },
448c5f01b2fSopenharmony_ci            { 0x88FCF317F22241E2,   588,  196 },
449c5f01b2fSopenharmony_ci            { 0xCC20CE9BD35C78A5,   614,  204 },
450c5f01b2fSopenharmony_ci            { 0x98165AF37B2153DF,   641,  212 },
451c5f01b2fSopenharmony_ci            { 0xE2A0B5DC971F303A,   667,  220 },
452c5f01b2fSopenharmony_ci            { 0xA8D9D1535CE3B396,   694,  228 },
453c5f01b2fSopenharmony_ci            { 0xFB9B7CD9A4A7443C,   720,  236 },
454c5f01b2fSopenharmony_ci            { 0xBB764C4CA7A44410,   747,  244 },
455c5f01b2fSopenharmony_ci            { 0x8BAB8EEFB6409C1A,   774,  252 },
456c5f01b2fSopenharmony_ci            { 0xD01FEF10A657842C,   800,  260 },
457c5f01b2fSopenharmony_ci            { 0x9B10A4E5E9913129,   827,  268 },
458c5f01b2fSopenharmony_ci            { 0xE7109BFBA19C0C9D,   853,  276 },
459c5f01b2fSopenharmony_ci            { 0xAC2820D9623BF429,   880,  284 },
460c5f01b2fSopenharmony_ci            { 0x80444B5E7AA7CF85,   907,  292 },
461c5f01b2fSopenharmony_ci            { 0xBF21E44003ACDD2D,   933,  300 },
462c5f01b2fSopenharmony_ci            { 0x8E679C2F5E44FF8F,   960,  308 },
463c5f01b2fSopenharmony_ci            { 0xD433179D9C8CB841,   986,  316 },
464c5f01b2fSopenharmony_ci            { 0x9E19DB92B4E31BA9,  1013,  324 },
465c5f01b2fSopenharmony_ci        }
466c5f01b2fSopenharmony_ci    };
467c5f01b2fSopenharmony_ci
468c5f01b2fSopenharmony_ci    // This computation gives exactly the same results for k as
469c5f01b2fSopenharmony_ci    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
470c5f01b2fSopenharmony_ci    // for |e| <= 1500, but doesn't require floating-point operations.
471c5f01b2fSopenharmony_ci    // NB: log_10(2) ~= 78913 / 2^18
472c5f01b2fSopenharmony_ci    JSON_ASSERT(e >= -1500);
473c5f01b2fSopenharmony_ci    JSON_ASSERT(e <=  1500);
474c5f01b2fSopenharmony_ci    const int f = kAlpha - e - 1;
475c5f01b2fSopenharmony_ci    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
476c5f01b2fSopenharmony_ci
477c5f01b2fSopenharmony_ci    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
478c5f01b2fSopenharmony_ci    JSON_ASSERT(index >= 0);
479c5f01b2fSopenharmony_ci    JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
480c5f01b2fSopenharmony_ci
481c5f01b2fSopenharmony_ci    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
482c5f01b2fSopenharmony_ci    JSON_ASSERT(kAlpha <= cached.e + e + 64);
483c5f01b2fSopenharmony_ci    JSON_ASSERT(kGamma >= cached.e + e + 64);
484c5f01b2fSopenharmony_ci
485c5f01b2fSopenharmony_ci    return cached;
486c5f01b2fSopenharmony_ci}
487c5f01b2fSopenharmony_ci
488c5f01b2fSopenharmony_ci/*!
489c5f01b2fSopenharmony_ciFor n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
490c5f01b2fSopenharmony_ciFor n == 0, returns 1 and sets pow10 := 1.
491c5f01b2fSopenharmony_ci*/
492c5f01b2fSopenharmony_ciinline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
493c5f01b2fSopenharmony_ci{
494c5f01b2fSopenharmony_ci    // LCOV_EXCL_START
495c5f01b2fSopenharmony_ci    if (n >= 1000000000)
496c5f01b2fSopenharmony_ci    {
497c5f01b2fSopenharmony_ci        pow10 = 1000000000;
498c5f01b2fSopenharmony_ci        return 10;
499c5f01b2fSopenharmony_ci    }
500c5f01b2fSopenharmony_ci    // LCOV_EXCL_STOP
501c5f01b2fSopenharmony_ci    if (n >= 100000000)
502c5f01b2fSopenharmony_ci    {
503c5f01b2fSopenharmony_ci        pow10 = 100000000;
504c5f01b2fSopenharmony_ci        return  9;
505c5f01b2fSopenharmony_ci    }
506c5f01b2fSopenharmony_ci    if (n >= 10000000)
507c5f01b2fSopenharmony_ci    {
508c5f01b2fSopenharmony_ci        pow10 = 10000000;
509c5f01b2fSopenharmony_ci        return  8;
510c5f01b2fSopenharmony_ci    }
511c5f01b2fSopenharmony_ci    if (n >= 1000000)
512c5f01b2fSopenharmony_ci    {
513c5f01b2fSopenharmony_ci        pow10 = 1000000;
514c5f01b2fSopenharmony_ci        return  7;
515c5f01b2fSopenharmony_ci    }
516c5f01b2fSopenharmony_ci    if (n >= 100000)
517c5f01b2fSopenharmony_ci    {
518c5f01b2fSopenharmony_ci        pow10 = 100000;
519c5f01b2fSopenharmony_ci        return  6;
520c5f01b2fSopenharmony_ci    }
521c5f01b2fSopenharmony_ci    if (n >= 10000)
522c5f01b2fSopenharmony_ci    {
523c5f01b2fSopenharmony_ci        pow10 = 10000;
524c5f01b2fSopenharmony_ci        return  5;
525c5f01b2fSopenharmony_ci    }
526c5f01b2fSopenharmony_ci    if (n >= 1000)
527c5f01b2fSopenharmony_ci    {
528c5f01b2fSopenharmony_ci        pow10 = 1000;
529c5f01b2fSopenharmony_ci        return  4;
530c5f01b2fSopenharmony_ci    }
531c5f01b2fSopenharmony_ci    if (n >= 100)
532c5f01b2fSopenharmony_ci    {
533c5f01b2fSopenharmony_ci        pow10 = 100;
534c5f01b2fSopenharmony_ci        return  3;
535c5f01b2fSopenharmony_ci    }
536c5f01b2fSopenharmony_ci    if (n >= 10)
537c5f01b2fSopenharmony_ci    {
538c5f01b2fSopenharmony_ci        pow10 = 10;
539c5f01b2fSopenharmony_ci        return  2;
540c5f01b2fSopenharmony_ci    }
541c5f01b2fSopenharmony_ci
542c5f01b2fSopenharmony_ci    pow10 = 1;
543c5f01b2fSopenharmony_ci    return 1;
544c5f01b2fSopenharmony_ci}
545c5f01b2fSopenharmony_ci
546c5f01b2fSopenharmony_ciinline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
547c5f01b2fSopenharmony_ci                         std::uint64_t rest, std::uint64_t ten_k)
548c5f01b2fSopenharmony_ci{
549c5f01b2fSopenharmony_ci    JSON_ASSERT(len >= 1);
550c5f01b2fSopenharmony_ci    JSON_ASSERT(dist <= delta);
551c5f01b2fSopenharmony_ci    JSON_ASSERT(rest <= delta);
552c5f01b2fSopenharmony_ci    JSON_ASSERT(ten_k > 0);
553c5f01b2fSopenharmony_ci
554c5f01b2fSopenharmony_ci    //               <--------------------------- delta ---->
555c5f01b2fSopenharmony_ci    //                                  <---- dist --------->
556c5f01b2fSopenharmony_ci    // --------------[------------------+-------------------]--------------
557c5f01b2fSopenharmony_ci    //               M-                 w                   M+
558c5f01b2fSopenharmony_ci    //
559c5f01b2fSopenharmony_ci    //                                  ten_k
560c5f01b2fSopenharmony_ci    //                                <------>
561c5f01b2fSopenharmony_ci    //                                       <---- rest ---->
562c5f01b2fSopenharmony_ci    // --------------[------------------+----+--------------]--------------
563c5f01b2fSopenharmony_ci    //                                  w    V
564c5f01b2fSopenharmony_ci    //                                       = buf * 10^k
565c5f01b2fSopenharmony_ci    //
566c5f01b2fSopenharmony_ci    // ten_k represents a unit-in-the-last-place in the decimal representation
567c5f01b2fSopenharmony_ci    // stored in buf.
568c5f01b2fSopenharmony_ci    // Decrement buf by ten_k while this takes buf closer to w.
569c5f01b2fSopenharmony_ci
570c5f01b2fSopenharmony_ci    // The tests are written in this order to avoid overflow in unsigned
571c5f01b2fSopenharmony_ci    // integer arithmetic.
572c5f01b2fSopenharmony_ci
573c5f01b2fSopenharmony_ci    while (rest < dist
574c5f01b2fSopenharmony_ci            && delta - rest >= ten_k
575c5f01b2fSopenharmony_ci            && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
576c5f01b2fSopenharmony_ci    {
577c5f01b2fSopenharmony_ci        JSON_ASSERT(buf[len - 1] != '0');
578c5f01b2fSopenharmony_ci        buf[len - 1]--;
579c5f01b2fSopenharmony_ci        rest += ten_k;
580c5f01b2fSopenharmony_ci    }
581c5f01b2fSopenharmony_ci}
582c5f01b2fSopenharmony_ci
583c5f01b2fSopenharmony_ci/*!
584c5f01b2fSopenharmony_ciGenerates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
585c5f01b2fSopenharmony_ciM- and M+ must be normalized and share the same exponent -60 <= e <= -32.
586c5f01b2fSopenharmony_ci*/
587c5f01b2fSopenharmony_ciinline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
588c5f01b2fSopenharmony_ci                             diyfp M_minus, diyfp w, diyfp M_plus)
589c5f01b2fSopenharmony_ci{
590c5f01b2fSopenharmony_ci    static_assert(kAlpha >= -60, "internal error");
591c5f01b2fSopenharmony_ci    static_assert(kGamma <= -32, "internal error");
592c5f01b2fSopenharmony_ci
593c5f01b2fSopenharmony_ci    // Generates the digits (and the exponent) of a decimal floating-point
594c5f01b2fSopenharmony_ci    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
595c5f01b2fSopenharmony_ci    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
596c5f01b2fSopenharmony_ci    //
597c5f01b2fSopenharmony_ci    //               <--------------------------- delta ---->
598c5f01b2fSopenharmony_ci    //                                  <---- dist --------->
599c5f01b2fSopenharmony_ci    // --------------[------------------+-------------------]--------------
600c5f01b2fSopenharmony_ci    //               M-                 w                   M+
601c5f01b2fSopenharmony_ci    //
602c5f01b2fSopenharmony_ci    // Grisu2 generates the digits of M+ from left to right and stops as soon as
603c5f01b2fSopenharmony_ci    // V is in [M-,M+].
604c5f01b2fSopenharmony_ci
605c5f01b2fSopenharmony_ci    JSON_ASSERT(M_plus.e >= kAlpha);
606c5f01b2fSopenharmony_ci    JSON_ASSERT(M_plus.e <= kGamma);
607c5f01b2fSopenharmony_ci
608c5f01b2fSopenharmony_ci    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
609c5f01b2fSopenharmony_ci    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
610c5f01b2fSopenharmony_ci
611c5f01b2fSopenharmony_ci    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
612c5f01b2fSopenharmony_ci    //
613c5f01b2fSopenharmony_ci    //      M+ = f * 2^e
614c5f01b2fSopenharmony_ci    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
615c5f01b2fSopenharmony_ci    //         = ((p1        ) * 2^-e + (p2        )) * 2^e
616c5f01b2fSopenharmony_ci    //         = p1 + p2 * 2^e
617c5f01b2fSopenharmony_ci
618c5f01b2fSopenharmony_ci    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
619c5f01b2fSopenharmony_ci
620c5f01b2fSopenharmony_ci    auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
621c5f01b2fSopenharmony_ci    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
622c5f01b2fSopenharmony_ci
623c5f01b2fSopenharmony_ci    // 1)
624c5f01b2fSopenharmony_ci    //
625c5f01b2fSopenharmony_ci    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
626c5f01b2fSopenharmony_ci
627c5f01b2fSopenharmony_ci    JSON_ASSERT(p1 > 0);
628c5f01b2fSopenharmony_ci
629c5f01b2fSopenharmony_ci    std::uint32_t pow10{};
630c5f01b2fSopenharmony_ci    const int k = find_largest_pow10(p1, pow10);
631c5f01b2fSopenharmony_ci
632c5f01b2fSopenharmony_ci    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
633c5f01b2fSopenharmony_ci    //
634c5f01b2fSopenharmony_ci    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
635c5f01b2fSopenharmony_ci    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
636c5f01b2fSopenharmony_ci    //
637c5f01b2fSopenharmony_ci    //      M+ = p1                                             + p2 * 2^e
638c5f01b2fSopenharmony_ci    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
639c5f01b2fSopenharmony_ci    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
640c5f01b2fSopenharmony_ci    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
641c5f01b2fSopenharmony_ci    //
642c5f01b2fSopenharmony_ci    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
643c5f01b2fSopenharmony_ci    //
644c5f01b2fSopenharmony_ci    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
645c5f01b2fSopenharmony_ci    //
646c5f01b2fSopenharmony_ci    // but stop as soon as
647c5f01b2fSopenharmony_ci    //
648c5f01b2fSopenharmony_ci    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
649c5f01b2fSopenharmony_ci
650c5f01b2fSopenharmony_ci    int n = k;
651c5f01b2fSopenharmony_ci    while (n > 0)
652c5f01b2fSopenharmony_ci    {
653c5f01b2fSopenharmony_ci        // Invariants:
654c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
655c5f01b2fSopenharmony_ci        //      pow10 = 10^(n-1) <= p1 < 10^n
656c5f01b2fSopenharmony_ci        //
657c5f01b2fSopenharmony_ci        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
658c5f01b2fSopenharmony_ci        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
659c5f01b2fSopenharmony_ci        //
660c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
661c5f01b2fSopenharmony_ci        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
662c5f01b2fSopenharmony_ci        //
663c5f01b2fSopenharmony_ci        JSON_ASSERT(d <= 9);
664c5f01b2fSopenharmony_ci        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
665c5f01b2fSopenharmony_ci        //
666c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
667c5f01b2fSopenharmony_ci        //
668c5f01b2fSopenharmony_ci        p1 = r;
669c5f01b2fSopenharmony_ci        n--;
670c5f01b2fSopenharmony_ci        //
671c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
672c5f01b2fSopenharmony_ci        //      pow10 = 10^n
673c5f01b2fSopenharmony_ci        //
674c5f01b2fSopenharmony_ci
675c5f01b2fSopenharmony_ci        // Now check if enough digits have been generated.
676c5f01b2fSopenharmony_ci        // Compute
677c5f01b2fSopenharmony_ci        //
678c5f01b2fSopenharmony_ci        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
679c5f01b2fSopenharmony_ci        //
680c5f01b2fSopenharmony_ci        // Note:
681c5f01b2fSopenharmony_ci        // Since rest and delta share the same exponent e, it suffices to
682c5f01b2fSopenharmony_ci        // compare the significands.
683c5f01b2fSopenharmony_ci        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
684c5f01b2fSopenharmony_ci        if (rest <= delta)
685c5f01b2fSopenharmony_ci        {
686c5f01b2fSopenharmony_ci            // V = buffer * 10^n, with M- <= V <= M+.
687c5f01b2fSopenharmony_ci
688c5f01b2fSopenharmony_ci            decimal_exponent += n;
689c5f01b2fSopenharmony_ci
690c5f01b2fSopenharmony_ci            // We may now just stop. But instead look if the buffer could be
691c5f01b2fSopenharmony_ci            // decremented to bring V closer to w.
692c5f01b2fSopenharmony_ci            //
693c5f01b2fSopenharmony_ci            // pow10 = 10^n is now 1 ulp in the decimal representation V.
694c5f01b2fSopenharmony_ci            // The rounding procedure works with diyfp's with an implicit
695c5f01b2fSopenharmony_ci            // exponent of e.
696c5f01b2fSopenharmony_ci            //
697c5f01b2fSopenharmony_ci            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
698c5f01b2fSopenharmony_ci            //
699c5f01b2fSopenharmony_ci            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
700c5f01b2fSopenharmony_ci            grisu2_round(buffer, length, dist, delta, rest, ten_n);
701c5f01b2fSopenharmony_ci
702c5f01b2fSopenharmony_ci            return;
703c5f01b2fSopenharmony_ci        }
704c5f01b2fSopenharmony_ci
705c5f01b2fSopenharmony_ci        pow10 /= 10;
706c5f01b2fSopenharmony_ci        //
707c5f01b2fSopenharmony_ci        //      pow10 = 10^(n-1) <= p1 < 10^n
708c5f01b2fSopenharmony_ci        // Invariants restored.
709c5f01b2fSopenharmony_ci    }
710c5f01b2fSopenharmony_ci
711c5f01b2fSopenharmony_ci    // 2)
712c5f01b2fSopenharmony_ci    //
713c5f01b2fSopenharmony_ci    // The digits of the integral part have been generated:
714c5f01b2fSopenharmony_ci    //
715c5f01b2fSopenharmony_ci    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
716c5f01b2fSopenharmony_ci    //         = buffer            + p2 * 2^e
717c5f01b2fSopenharmony_ci    //
718c5f01b2fSopenharmony_ci    // Now generate the digits of the fractional part p2 * 2^e.
719c5f01b2fSopenharmony_ci    //
720c5f01b2fSopenharmony_ci    // Note:
721c5f01b2fSopenharmony_ci    // No decimal point is generated: the exponent is adjusted instead.
722c5f01b2fSopenharmony_ci    //
723c5f01b2fSopenharmony_ci    // p2 actually represents the fraction
724c5f01b2fSopenharmony_ci    //
725c5f01b2fSopenharmony_ci    //      p2 * 2^e
726c5f01b2fSopenharmony_ci    //          = p2 / 2^-e
727c5f01b2fSopenharmony_ci    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
728c5f01b2fSopenharmony_ci    //
729c5f01b2fSopenharmony_ci    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
730c5f01b2fSopenharmony_ci    //
731c5f01b2fSopenharmony_ci    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
732c5f01b2fSopenharmony_ci    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
733c5f01b2fSopenharmony_ci    //
734c5f01b2fSopenharmony_ci    // using
735c5f01b2fSopenharmony_ci    //
736c5f01b2fSopenharmony_ci    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
737c5f01b2fSopenharmony_ci    //                = (                   d) * 2^-e + (                   r)
738c5f01b2fSopenharmony_ci    //
739c5f01b2fSopenharmony_ci    // or
740c5f01b2fSopenharmony_ci    //      10^m * p2 * 2^e = d + r * 2^e
741c5f01b2fSopenharmony_ci    //
742c5f01b2fSopenharmony_ci    // i.e.
743c5f01b2fSopenharmony_ci    //
744c5f01b2fSopenharmony_ci    //      M+ = buffer + p2 * 2^e
745c5f01b2fSopenharmony_ci    //         = buffer + 10^-m * (d + r * 2^e)
746c5f01b2fSopenharmony_ci    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
747c5f01b2fSopenharmony_ci    //
748c5f01b2fSopenharmony_ci    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
749c5f01b2fSopenharmony_ci
750c5f01b2fSopenharmony_ci    JSON_ASSERT(p2 > delta);
751c5f01b2fSopenharmony_ci
752c5f01b2fSopenharmony_ci    int m = 0;
753c5f01b2fSopenharmony_ci    for (;;)
754c5f01b2fSopenharmony_ci    {
755c5f01b2fSopenharmony_ci        // Invariant:
756c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
757c5f01b2fSopenharmony_ci        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
758c5f01b2fSopenharmony_ci        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
759c5f01b2fSopenharmony_ci        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
760c5f01b2fSopenharmony_ci        //
761c5f01b2fSopenharmony_ci        JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
762c5f01b2fSopenharmony_ci        p2 *= 10;
763c5f01b2fSopenharmony_ci        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
764c5f01b2fSopenharmony_ci        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
765c5f01b2fSopenharmony_ci        //
766c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
767c5f01b2fSopenharmony_ci        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
768c5f01b2fSopenharmony_ci        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
769c5f01b2fSopenharmony_ci        //
770c5f01b2fSopenharmony_ci        JSON_ASSERT(d <= 9);
771c5f01b2fSopenharmony_ci        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
772c5f01b2fSopenharmony_ci        //
773c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
774c5f01b2fSopenharmony_ci        //
775c5f01b2fSopenharmony_ci        p2 = r;
776c5f01b2fSopenharmony_ci        m++;
777c5f01b2fSopenharmony_ci        //
778c5f01b2fSopenharmony_ci        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
779c5f01b2fSopenharmony_ci        // Invariant restored.
780c5f01b2fSopenharmony_ci
781c5f01b2fSopenharmony_ci        // Check if enough digits have been generated.
782c5f01b2fSopenharmony_ci        //
783c5f01b2fSopenharmony_ci        //      10^-m * p2 * 2^e <= delta * 2^e
784c5f01b2fSopenharmony_ci        //              p2 * 2^e <= 10^m * delta * 2^e
785c5f01b2fSopenharmony_ci        //                    p2 <= 10^m * delta
786c5f01b2fSopenharmony_ci        delta *= 10;
787c5f01b2fSopenharmony_ci        dist  *= 10;
788c5f01b2fSopenharmony_ci        if (p2 <= delta)
789c5f01b2fSopenharmony_ci        {
790c5f01b2fSopenharmony_ci            break;
791c5f01b2fSopenharmony_ci        }
792c5f01b2fSopenharmony_ci    }
793c5f01b2fSopenharmony_ci
794c5f01b2fSopenharmony_ci    // V = buffer * 10^-m, with M- <= V <= M+.
795c5f01b2fSopenharmony_ci
796c5f01b2fSopenharmony_ci    decimal_exponent -= m;
797c5f01b2fSopenharmony_ci
798c5f01b2fSopenharmony_ci    // 1 ulp in the decimal representation is now 10^-m.
799c5f01b2fSopenharmony_ci    // Since delta and dist are now scaled by 10^m, we need to do the
800c5f01b2fSopenharmony_ci    // same with ulp in order to keep the units in sync.
801c5f01b2fSopenharmony_ci    //
802c5f01b2fSopenharmony_ci    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
803c5f01b2fSopenharmony_ci    //
804c5f01b2fSopenharmony_ci    const std::uint64_t ten_m = one.f;
805c5f01b2fSopenharmony_ci    grisu2_round(buffer, length, dist, delta, p2, ten_m);
806c5f01b2fSopenharmony_ci
807c5f01b2fSopenharmony_ci    // By construction this algorithm generates the shortest possible decimal
808c5f01b2fSopenharmony_ci    // number (Loitsch, Theorem 6.2) which rounds back to w.
809c5f01b2fSopenharmony_ci    // For an input number of precision p, at least
810c5f01b2fSopenharmony_ci    //
811c5f01b2fSopenharmony_ci    //      N = 1 + ceil(p * log_10(2))
812c5f01b2fSopenharmony_ci    //
813c5f01b2fSopenharmony_ci    // decimal digits are sufficient to identify all binary floating-point
814c5f01b2fSopenharmony_ci    // numbers (Matula, "In-and-Out conversions").
815c5f01b2fSopenharmony_ci    // This implies that the algorithm does not produce more than N decimal
816c5f01b2fSopenharmony_ci    // digits.
817c5f01b2fSopenharmony_ci    //
818c5f01b2fSopenharmony_ci    //      N = 17 for p = 53 (IEEE double precision)
819c5f01b2fSopenharmony_ci    //      N = 9  for p = 24 (IEEE single precision)
820c5f01b2fSopenharmony_ci}
821c5f01b2fSopenharmony_ci
822c5f01b2fSopenharmony_ci/*!
823c5f01b2fSopenharmony_civ = buf * 10^decimal_exponent
824c5f01b2fSopenharmony_cilen is the length of the buffer (number of decimal digits)
825c5f01b2fSopenharmony_ciThe buffer must be large enough, i.e. >= max_digits10.
826c5f01b2fSopenharmony_ci*/
827c5f01b2fSopenharmony_ciJSON_HEDLEY_NON_NULL(1)
828c5f01b2fSopenharmony_ciinline void grisu2(char* buf, int& len, int& decimal_exponent,
829c5f01b2fSopenharmony_ci                   diyfp m_minus, diyfp v, diyfp m_plus)
830c5f01b2fSopenharmony_ci{
831c5f01b2fSopenharmony_ci    JSON_ASSERT(m_plus.e == m_minus.e);
832c5f01b2fSopenharmony_ci    JSON_ASSERT(m_plus.e == v.e);
833c5f01b2fSopenharmony_ci
834c5f01b2fSopenharmony_ci    //  --------(-----------------------+-----------------------)--------    (A)
835c5f01b2fSopenharmony_ci    //          m-                      v                       m+
836c5f01b2fSopenharmony_ci    //
837c5f01b2fSopenharmony_ci    //  --------------------(-----------+-----------------------)--------    (B)
838c5f01b2fSopenharmony_ci    //                      m-          v                       m+
839c5f01b2fSopenharmony_ci    //
840c5f01b2fSopenharmony_ci    // First scale v (and m- and m+) such that the exponent is in the range
841c5f01b2fSopenharmony_ci    // [alpha, gamma].
842c5f01b2fSopenharmony_ci
843c5f01b2fSopenharmony_ci    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
844c5f01b2fSopenharmony_ci
845c5f01b2fSopenharmony_ci    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
846c5f01b2fSopenharmony_ci
847c5f01b2fSopenharmony_ci    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
848c5f01b2fSopenharmony_ci    const diyfp w       = diyfp::mul(v,       c_minus_k);
849c5f01b2fSopenharmony_ci    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
850c5f01b2fSopenharmony_ci    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
851c5f01b2fSopenharmony_ci
852c5f01b2fSopenharmony_ci    //  ----(---+---)---------------(---+---)---------------(---+---)----
853c5f01b2fSopenharmony_ci    //          w-                      w                       w+
854c5f01b2fSopenharmony_ci    //          = c*m-                  = c*v                   = c*m+
855c5f01b2fSopenharmony_ci    //
856c5f01b2fSopenharmony_ci    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
857c5f01b2fSopenharmony_ci    // w+ are now off by a small amount.
858c5f01b2fSopenharmony_ci    // In fact:
859c5f01b2fSopenharmony_ci    //
860c5f01b2fSopenharmony_ci    //      w - v * 10^k < 1 ulp
861c5f01b2fSopenharmony_ci    //
862c5f01b2fSopenharmony_ci    // To account for this inaccuracy, add resp. subtract 1 ulp.
863c5f01b2fSopenharmony_ci    //
864c5f01b2fSopenharmony_ci    //  --------+---[---------------(---+---)---------------]---+--------
865c5f01b2fSopenharmony_ci    //          w-  M-                  w                   M+  w+
866c5f01b2fSopenharmony_ci    //
867c5f01b2fSopenharmony_ci    // Now any number in [M-, M+] (bounds included) will round to w when input,
868c5f01b2fSopenharmony_ci    // regardless of how the input rounding algorithm breaks ties.
869c5f01b2fSopenharmony_ci    //
870c5f01b2fSopenharmony_ci    // And digit_gen generates the shortest possible such number in [M-, M+].
871c5f01b2fSopenharmony_ci    // Note that this does not mean that Grisu2 always generates the shortest
872c5f01b2fSopenharmony_ci    // possible number in the interval (m-, m+).
873c5f01b2fSopenharmony_ci    const diyfp M_minus(w_minus.f + 1, w_minus.e);
874c5f01b2fSopenharmony_ci    const diyfp M_plus (w_plus.f  - 1, w_plus.e );
875c5f01b2fSopenharmony_ci
876c5f01b2fSopenharmony_ci    decimal_exponent = -cached.k; // = -(-k) = k
877c5f01b2fSopenharmony_ci
878c5f01b2fSopenharmony_ci    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
879c5f01b2fSopenharmony_ci}
880c5f01b2fSopenharmony_ci
881c5f01b2fSopenharmony_ci/*!
882c5f01b2fSopenharmony_civ = buf * 10^decimal_exponent
883c5f01b2fSopenharmony_cilen is the length of the buffer (number of decimal digits)
884c5f01b2fSopenharmony_ciThe buffer must be large enough, i.e. >= max_digits10.
885c5f01b2fSopenharmony_ci*/
886c5f01b2fSopenharmony_citemplate<typename FloatType>
887c5f01b2fSopenharmony_ciJSON_HEDLEY_NON_NULL(1)
888c5f01b2fSopenharmony_civoid grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
889c5f01b2fSopenharmony_ci{
890c5f01b2fSopenharmony_ci    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
891c5f01b2fSopenharmony_ci                  "internal error: not enough precision");
892c5f01b2fSopenharmony_ci
893c5f01b2fSopenharmony_ci    JSON_ASSERT(std::isfinite(value));
894c5f01b2fSopenharmony_ci    JSON_ASSERT(value > 0);
895c5f01b2fSopenharmony_ci
896c5f01b2fSopenharmony_ci    // If the neighbors (and boundaries) of 'value' are always computed for double-precision
897c5f01b2fSopenharmony_ci    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
898c5f01b2fSopenharmony_ci    // decimal representations are not exactly "short".
899c5f01b2fSopenharmony_ci    //
900c5f01b2fSopenharmony_ci    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
901c5f01b2fSopenharmony_ci    // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
902c5f01b2fSopenharmony_ci    // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
903c5f01b2fSopenharmony_ci    // does.
904c5f01b2fSopenharmony_ci    // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
905c5f01b2fSopenharmony_ci    // representation using the corresponding std::from_chars function recovers value exactly". That
906c5f01b2fSopenharmony_ci    // indicates that single precision floating-point numbers should be recovered using
907c5f01b2fSopenharmony_ci    // 'std::strtof'.
908c5f01b2fSopenharmony_ci    //
909c5f01b2fSopenharmony_ci    // NB: If the neighbors are computed for single-precision numbers, there is a single float
910c5f01b2fSopenharmony_ci    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
911c5f01b2fSopenharmony_ci    //     value is off by 1 ulp.
912c5f01b2fSopenharmony_ci#if 0
913c5f01b2fSopenharmony_ci    const boundaries w = compute_boundaries(static_cast<double>(value));
914c5f01b2fSopenharmony_ci#else
915c5f01b2fSopenharmony_ci    const boundaries w = compute_boundaries(value);
916c5f01b2fSopenharmony_ci#endif
917c5f01b2fSopenharmony_ci
918c5f01b2fSopenharmony_ci    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
919c5f01b2fSopenharmony_ci}
920c5f01b2fSopenharmony_ci
921c5f01b2fSopenharmony_ci/*!
922c5f01b2fSopenharmony_ci@brief appends a decimal representation of e to buf
923c5f01b2fSopenharmony_ci@return a pointer to the element following the exponent.
924c5f01b2fSopenharmony_ci@pre -1000 < e < 1000
925c5f01b2fSopenharmony_ci*/
926c5f01b2fSopenharmony_ciJSON_HEDLEY_NON_NULL(1)
927c5f01b2fSopenharmony_ciJSON_HEDLEY_RETURNS_NON_NULL
928c5f01b2fSopenharmony_ciinline char* append_exponent(char* buf, int e)
929c5f01b2fSopenharmony_ci{
930c5f01b2fSopenharmony_ci    JSON_ASSERT(e > -1000);
931c5f01b2fSopenharmony_ci    JSON_ASSERT(e <  1000);
932c5f01b2fSopenharmony_ci
933c5f01b2fSopenharmony_ci    if (e < 0)
934c5f01b2fSopenharmony_ci    {
935c5f01b2fSopenharmony_ci        e = -e;
936c5f01b2fSopenharmony_ci        *buf++ = '-';
937c5f01b2fSopenharmony_ci    }
938c5f01b2fSopenharmony_ci    else
939c5f01b2fSopenharmony_ci    {
940c5f01b2fSopenharmony_ci        *buf++ = '+';
941c5f01b2fSopenharmony_ci    }
942c5f01b2fSopenharmony_ci
943c5f01b2fSopenharmony_ci    auto k = static_cast<std::uint32_t>(e);
944c5f01b2fSopenharmony_ci    if (k < 10)
945c5f01b2fSopenharmony_ci    {
946c5f01b2fSopenharmony_ci        // Always print at least two digits in the exponent.
947c5f01b2fSopenharmony_ci        // This is for compatibility with printf("%g").
948c5f01b2fSopenharmony_ci        *buf++ = '0';
949c5f01b2fSopenharmony_ci        *buf++ = static_cast<char>('0' + k);
950c5f01b2fSopenharmony_ci    }
951c5f01b2fSopenharmony_ci    else if (k < 100)
952c5f01b2fSopenharmony_ci    {
953c5f01b2fSopenharmony_ci        *buf++ = static_cast<char>('0' + k / 10);
954c5f01b2fSopenharmony_ci        k %= 10;
955c5f01b2fSopenharmony_ci        *buf++ = static_cast<char>('0' + k);
956c5f01b2fSopenharmony_ci    }
957c5f01b2fSopenharmony_ci    else
958c5f01b2fSopenharmony_ci    {
959c5f01b2fSopenharmony_ci        *buf++ = static_cast<char>('0' + k / 100);
960c5f01b2fSopenharmony_ci        k %= 100;
961c5f01b2fSopenharmony_ci        *buf++ = static_cast<char>('0' + k / 10);
962c5f01b2fSopenharmony_ci        k %= 10;
963c5f01b2fSopenharmony_ci        *buf++ = static_cast<char>('0' + k);
964c5f01b2fSopenharmony_ci    }
965c5f01b2fSopenharmony_ci
966c5f01b2fSopenharmony_ci    return buf;
967c5f01b2fSopenharmony_ci}
968c5f01b2fSopenharmony_ci
969c5f01b2fSopenharmony_ci/*!
970c5f01b2fSopenharmony_ci@brief prettify v = buf * 10^decimal_exponent
971c5f01b2fSopenharmony_ci
972c5f01b2fSopenharmony_ciIf v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
973c5f01b2fSopenharmony_cinotation. Otherwise it will be printed in exponential notation.
974c5f01b2fSopenharmony_ci
975c5f01b2fSopenharmony_ci@pre min_exp < 0
976c5f01b2fSopenharmony_ci@pre max_exp > 0
977c5f01b2fSopenharmony_ci*/
978c5f01b2fSopenharmony_ciJSON_HEDLEY_NON_NULL(1)
979c5f01b2fSopenharmony_ciJSON_HEDLEY_RETURNS_NON_NULL
980c5f01b2fSopenharmony_ciinline char* format_buffer(char* buf, int len, int decimal_exponent,
981c5f01b2fSopenharmony_ci                           int min_exp, int max_exp)
982c5f01b2fSopenharmony_ci{
983c5f01b2fSopenharmony_ci    JSON_ASSERT(min_exp < 0);
984c5f01b2fSopenharmony_ci    JSON_ASSERT(max_exp > 0);
985c5f01b2fSopenharmony_ci
986c5f01b2fSopenharmony_ci    const int k = len;
987c5f01b2fSopenharmony_ci    const int n = len + decimal_exponent;
988c5f01b2fSopenharmony_ci
989c5f01b2fSopenharmony_ci    // v = buf * 10^(n-k)
990c5f01b2fSopenharmony_ci    // k is the length of the buffer (number of decimal digits)
991c5f01b2fSopenharmony_ci    // n is the position of the decimal point relative to the start of the buffer.
992c5f01b2fSopenharmony_ci
993c5f01b2fSopenharmony_ci    if (k <= n && n <= max_exp)
994c5f01b2fSopenharmony_ci    {
995c5f01b2fSopenharmony_ci        // digits[000]
996c5f01b2fSopenharmony_ci        // len <= max_exp + 2
997c5f01b2fSopenharmony_ci
998c5f01b2fSopenharmony_ci        std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
999c5f01b2fSopenharmony_ci        // Make it look like a floating-point number (#362, #378)
1000c5f01b2fSopenharmony_ci        buf[n + 0] = '.';
1001c5f01b2fSopenharmony_ci        buf[n + 1] = '0';
1002c5f01b2fSopenharmony_ci        return buf + (static_cast<size_t>(n) + 2);
1003c5f01b2fSopenharmony_ci    }
1004c5f01b2fSopenharmony_ci
1005c5f01b2fSopenharmony_ci    if (0 < n && n <= max_exp)
1006c5f01b2fSopenharmony_ci    {
1007c5f01b2fSopenharmony_ci        // dig.its
1008c5f01b2fSopenharmony_ci        // len <= max_digits10 + 1
1009c5f01b2fSopenharmony_ci
1010c5f01b2fSopenharmony_ci        JSON_ASSERT(k > n);
1011c5f01b2fSopenharmony_ci
1012c5f01b2fSopenharmony_ci        std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
1013c5f01b2fSopenharmony_ci        buf[n] = '.';
1014c5f01b2fSopenharmony_ci        return buf + (static_cast<size_t>(k) + 1U);
1015c5f01b2fSopenharmony_ci    }
1016c5f01b2fSopenharmony_ci
1017c5f01b2fSopenharmony_ci    if (min_exp < n && n <= 0)
1018c5f01b2fSopenharmony_ci    {
1019c5f01b2fSopenharmony_ci        // 0.[000]digits
1020c5f01b2fSopenharmony_ci        // len <= 2 + (-min_exp - 1) + max_digits10
1021c5f01b2fSopenharmony_ci
1022c5f01b2fSopenharmony_ci        std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
1023c5f01b2fSopenharmony_ci        buf[0] = '0';
1024c5f01b2fSopenharmony_ci        buf[1] = '.';
1025c5f01b2fSopenharmony_ci        std::memset(buf + 2, '0', static_cast<size_t>(-n));
1026c5f01b2fSopenharmony_ci        return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
1027c5f01b2fSopenharmony_ci    }
1028c5f01b2fSopenharmony_ci
1029c5f01b2fSopenharmony_ci    if (k == 1)
1030c5f01b2fSopenharmony_ci    {
1031c5f01b2fSopenharmony_ci        // dE+123
1032c5f01b2fSopenharmony_ci        // len <= 1 + 5
1033c5f01b2fSopenharmony_ci
1034c5f01b2fSopenharmony_ci        buf += 1;
1035c5f01b2fSopenharmony_ci    }
1036c5f01b2fSopenharmony_ci    else
1037c5f01b2fSopenharmony_ci    {
1038c5f01b2fSopenharmony_ci        // d.igitsE+123
1039c5f01b2fSopenharmony_ci        // len <= max_digits10 + 1 + 5
1040c5f01b2fSopenharmony_ci
1041c5f01b2fSopenharmony_ci        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
1042c5f01b2fSopenharmony_ci        buf[1] = '.';
1043c5f01b2fSopenharmony_ci        buf += 1 + static_cast<size_t>(k);
1044c5f01b2fSopenharmony_ci    }
1045c5f01b2fSopenharmony_ci
1046c5f01b2fSopenharmony_ci    *buf++ = 'e';
1047c5f01b2fSopenharmony_ci    return append_exponent(buf, n - 1);
1048c5f01b2fSopenharmony_ci}
1049c5f01b2fSopenharmony_ci
1050c5f01b2fSopenharmony_ci}  // namespace dtoa_impl
1051c5f01b2fSopenharmony_ci
1052c5f01b2fSopenharmony_ci/*!
1053c5f01b2fSopenharmony_ci@brief generates a decimal representation of the floating-point number value in [first, last).
1054c5f01b2fSopenharmony_ci
1055c5f01b2fSopenharmony_ciThe format of the resulting decimal representation is similar to printf's %g
1056c5f01b2fSopenharmony_ciformat. Returns an iterator pointing past-the-end of the decimal representation.
1057c5f01b2fSopenharmony_ci
1058c5f01b2fSopenharmony_ci@note The input number must be finite, i.e. NaN's and Inf's are not supported.
1059c5f01b2fSopenharmony_ci@note The buffer must be large enough.
1060c5f01b2fSopenharmony_ci@note The result is NOT null-terminated.
1061c5f01b2fSopenharmony_ci*/
1062c5f01b2fSopenharmony_citemplate<typename FloatType>
1063c5f01b2fSopenharmony_ciJSON_HEDLEY_NON_NULL(1, 2)
1064c5f01b2fSopenharmony_ciJSON_HEDLEY_RETURNS_NON_NULL
1065c5f01b2fSopenharmony_cichar* to_chars(char* first, const char* last, FloatType value)
1066c5f01b2fSopenharmony_ci{
1067c5f01b2fSopenharmony_ci    static_cast<void>(last); // maybe unused - fix warning
1068c5f01b2fSopenharmony_ci    JSON_ASSERT(std::isfinite(value));
1069c5f01b2fSopenharmony_ci
1070c5f01b2fSopenharmony_ci    // Use signbit(value) instead of (value < 0) since signbit works for -0.
1071c5f01b2fSopenharmony_ci    if (std::signbit(value))
1072c5f01b2fSopenharmony_ci    {
1073c5f01b2fSopenharmony_ci        value = -value;
1074c5f01b2fSopenharmony_ci        *first++ = '-';
1075c5f01b2fSopenharmony_ci    }
1076c5f01b2fSopenharmony_ci
1077c5f01b2fSopenharmony_ci#ifdef __GNUC__
1078c5f01b2fSopenharmony_ci#pragma GCC diagnostic push
1079c5f01b2fSopenharmony_ci#pragma GCC diagnostic ignored "-Wfloat-equal"
1080c5f01b2fSopenharmony_ci#endif
1081c5f01b2fSopenharmony_ci    if (value == 0) // +-0
1082c5f01b2fSopenharmony_ci    {
1083c5f01b2fSopenharmony_ci        *first++ = '0';
1084c5f01b2fSopenharmony_ci        // Make it look like a floating-point number (#362, #378)
1085c5f01b2fSopenharmony_ci        *first++ = '.';
1086c5f01b2fSopenharmony_ci        *first++ = '0';
1087c5f01b2fSopenharmony_ci        return first;
1088c5f01b2fSopenharmony_ci    }
1089c5f01b2fSopenharmony_ci#ifdef __GNUC__
1090c5f01b2fSopenharmony_ci#pragma GCC diagnostic pop
1091c5f01b2fSopenharmony_ci#endif
1092c5f01b2fSopenharmony_ci
1093c5f01b2fSopenharmony_ci    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
1094c5f01b2fSopenharmony_ci
1095c5f01b2fSopenharmony_ci    // Compute v = buffer * 10^decimal_exponent.
1096c5f01b2fSopenharmony_ci    // The decimal digits are stored in the buffer, which needs to be interpreted
1097c5f01b2fSopenharmony_ci    // as an unsigned decimal integer.
1098c5f01b2fSopenharmony_ci    // len is the length of the buffer, i.e. the number of decimal digits.
1099c5f01b2fSopenharmony_ci    int len = 0;
1100c5f01b2fSopenharmony_ci    int decimal_exponent = 0;
1101c5f01b2fSopenharmony_ci    dtoa_impl::grisu2(first, len, decimal_exponent, value);
1102c5f01b2fSopenharmony_ci
1103c5f01b2fSopenharmony_ci    JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
1104c5f01b2fSopenharmony_ci
1105c5f01b2fSopenharmony_ci    // Format the buffer like printf("%.*g", prec, value)
1106c5f01b2fSopenharmony_ci    constexpr int kMinExp = -4;
1107c5f01b2fSopenharmony_ci    // Use digits10 here to increase compatibility with version 2.
1108c5f01b2fSopenharmony_ci    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
1109c5f01b2fSopenharmony_ci
1110c5f01b2fSopenharmony_ci    JSON_ASSERT(last - first >= kMaxExp + 2);
1111c5f01b2fSopenharmony_ci    JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
1112c5f01b2fSopenharmony_ci    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
1113c5f01b2fSopenharmony_ci
1114c5f01b2fSopenharmony_ci    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
1115c5f01b2fSopenharmony_ci}
1116c5f01b2fSopenharmony_ci
1117c5f01b2fSopenharmony_ci}  // namespace detail
1118c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_END
1119