// File: Konano[P]UselessDatabase/./json.hpp
// Function: nlohmann::detail::dtoa_impl::grisu2_digit_gen(char*, int&, int&, nlohmann::detail::dtoa_impl::diyfp, nlohmann::detail::dtoa_impl::diyfp, nlohmann::detail::dtoa_impl::diyfp)
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
                             diyfp M_minus, diyfp w, diyfp M_plus)
{
    static_assert(kAlpha >= -60, "internal error");
    static_assert(kGamma <= -32, "internal error");

    // Generates the digits (and the exponent) of a decimal floating-point
    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
    //
    //               <--------------------------- delta ---->
    //                                  <---- dist --------->
    // --------------[------------------+-------------------]--------------
    //               M-                 w                   M+
    //
    // Grisu2 generates the digits of M+ from left to right and stops as soon as
    // V is in [M-,M+].

    assert(M_plus.e >= kAlpha);
    assert(M_plus.e <= kGamma);

    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)

    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
    //
    //      M+ = f * 2^e
    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
    //         = ((p1        ) * 2^-e + (p2        )) * 2^e
    //         = p1 + p2 * 2^e

    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);

    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.)
    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e

    // 1)
    //
    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]

    assert(p1 > 0);

    std::uint32_t pow10;
    const int k = find_largest_pow10(p1, pow10);

    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
    //
    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
    //
    //      M+ = p1                                             + p2 * 2^e
    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
    //
    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
    //
    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
    //
    // but stop as soon as
    //
    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e

    int n = k;
    while (n > 0)
    {
        // Invariants:
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
        //      pow10 = 10^(n-1) <= p1 < 10^n
        //
        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
        //
        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
        //
        assert(d <= 9);
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
        //
        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
        //
        p1 = r;
        n--;
        //
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
        //      pow10 = 10^n
        //

        // Now check if enough digits have been generated.
        // Compute
        //
        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
        //
        // Note:
        // Since rest and delta share the same exponent e, it suffices to
        // compare the significands.
        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
        if (rest <= delta)
        {
            // V = buffer * 10^n, with M- <= V <= M+.

            decimal_exponent += n;

            // We may now just stop. But instead look if the buffer could be
            // decremented to bring V closer to w.
            //
            // pow10 = 10^n is now 1 ulp in the decimal representation V.
            // The rounding procedure works with diyfp's with an implicit
            // exponent of e.
            //
            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
            //
            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
            grisu2_round(buffer, length, dist, delta, rest, ten_n);

            return;
        }

        pow10 /= 10;
        //
        //      pow10 = 10^(n-1) <= p1 < 10^n
        // Invariants restored.
    }

    // 2)
    //
    // The digits of the integral part have been generated:
    //
    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
    //         = buffer            + p2 * 2^e
    //
    // Now generate the digits of the fractional part p2 * 2^e.
    //
    // Note:
    // No decimal point is generated: the exponent is adjusted instead.
    //
    // p2 actually represents the fraction
    //
    //      p2 * 2^e
    //          = p2 / 2^-e
    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
    //
    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
    //
    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
    //
    // using
    //
    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
    //                = (                   d) * 2^-e + (                   r)
    //
    // or
    //      10^m * p2 * 2^e = d + r * 2^e
    //
    // i.e.
    //
    //      M+ = buffer + p2 * 2^e
    //         = buffer + 10^-m * (d + r * 2^e)
    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
    //
    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e

    assert(p2 > delta);

    int m = 0;
    for (;;)
    {
        // Invariant:
        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
        //
        assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
        p2 *= 10;
        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
        //
        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
        //
        assert(d <= 9);
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
        //
        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
        //
        p2 = r;
        m++;
        //
        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
        // Invariant restored.

        // Check if enough digits have been generated.
        //
        //      10^-m * p2 * 2^e <= delta * 2^e
        //              p2 * 2^e <= 10^m * delta * 2^e
        //                    p2 <= 10^m * delta
        delta *= 10;
        dist  *= 10;
        if (p2 <= delta)
        {
            break;
        }
    }

    // V = buffer * 10^-m, with M- <= V <= M+.

    decimal_exponent -= m;

    // 1 ulp in the decimal representation is now 10^-m.
    // Since delta and dist are now scaled by 10^m, we need to do the
    // same with ulp in order to keep the units in sync.
    //
    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
    //
    const std::uint64_t ten_m = one.f;
    grisu2_round(buffer, length, dist, delta, p2, ten_m);

    // By construction this algorithm generates the shortest possible decimal
    // number (Loitsch, Theorem 6.2) which rounds back to w.
    // For an input number of precision p, at least
    //
    //      N = 1 + ceil(p * log_10(2))
    //
    // decimal digits are sufficient to identify all binary floating-point
    // numbers (Matula, "In-and-Out conversions").
    // This implies that the algorithm does not produce more than N decimal
    // digits.
    //
    //      N = 17 for p = 53 (IEEE double precision)
    //      N = 9  for p = 24 (IEEE single precision)
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
leaq 0x20(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq 0x10(%rbp), %r9
movq %r9, -0xe8(%rbp)
movq %rcx, -0x10(%rbp)
movl %r8d, -0x8(%rbp)
movq %rdi, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movq %rdx, -0x28(%rbp)
cmpl $-0x3c, 0x8(%rax)
jl 0x1710d
jmp 0x1712c
leaq 0x6830a(%rip), %rdi     # 0x7f41e
leaq 0x67a26(%rip), %rsi     # 0x7eb41
movl $0x33c1, %edx           # imm = 0x33C1
leaq 0x6830a(%rip), %rcx     # 0x7f431
callq 0x6350
movq -0xf0(%rbp), %rax
cmpl $-0x20, 0x8(%rax)
jg 0x1713b
jmp 0x1715a
leaq 0x6834d(%rip), %rdi     # 0x7f48f
leaq 0x679f8(%rip), %rsi     # 0x7eb41
movl $0x33c2, %edx           # imm = 0x33C2
leaq 0x682dc(%rip), %rcx     # 0x7f431
callq 0x6350
movq -0xf0(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x175a0
movq -0xe8(%rbp), %rsi
movq -0xf0(%rbp), %rdi
movl %edx, -0x48(%rbp)
movq %rax, -0x50(%rbp)
movl -0x48(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x30(%rbp)
callq 0x175a0
movq %rax, %rcx
movq -0xf0(%rbp), %rax
movl %edx, -0x70(%rbp)
movq %rcx, -0x78(%rbp)
movq -0x78(%rbp), %rcx
movq %rcx, -0x68(%rbp)
movl -0x70(%rbp), %ecx
movl %ecx, -0x60(%rbp)
movq -0x68(%rbp), %rcx
movq %rcx, -0x58(%rbp)
xorl %ecx, %ecx
subl 0x8(%rax), %ecx
movl %ecx, %ecx
movl $0x1, %esi
shlq %cl, %rsi
movl 0x8(%rax), %edx
leaq -0x88(%rbp), %rdi
callq 0x16c90
movq -0xf0(%rbp), %rax
movq (%rax), %rdx
xorl %ecx, %ecx
subl -0x80(%rbp), %ecx
movl %ecx, %ecx
shrq %cl, %rdx
movq %rdx, %rcx
movl %ecx, -0x8c(%rbp)
movq (%rax), %rax
movq -0x88(%rbp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, -0x98(%rbp)
cmpl $0x0, -0x8c(%rbp)
jbe 0x1721f
jmp 0x1723e
leaq 0x6827c(%rip), %rdi     # 0x7f4a2
leaq 0x67914(%rip), %rsi     # 0x7eb41
movl $0x33d7, %edx           # imm = 0x33D7
leaq 0x681f8(%rip), %rcx     # 0x7f431
callq 0x6350
movl -0x8c(%rbp), %edi
leaq -0x9c(%rbp), %rsi
callq 0x17640
movl %eax, -0xa0(%rbp)
movl -0xa0(%rbp), %eax
movl %eax, -0xa4(%rbp)
cmpl $0x0, -0xa4(%rbp)
jle 0x17392
movl -0x8c(%rbp), %eax
xorl %edx, %edx
divl -0x9c(%rbp)
movl %eax, -0xa8(%rbp)
movl -0x8c(%rbp), %eax
xorl %edx, %edx
divl -0x9c(%rbp)
movl %edx, -0xac(%rbp)
cmpl $0x9, -0xa8(%rbp)
ja 0x172a2
jmp 0x172c1
leaq 0x68200(%rip), %rdi     # 0x7f4a9
leaq 0x67891(%rip), %rsi     # 0x7eb41
movl $0x33fb, %edx           # imm = 0x33FB
leaq 0x68175(%rip), %rcx     # 0x7f431
callq 0x6350
movl -0xa8(%rbp), %eax
addl $0x30, %eax
movb %al, %dl
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0xac(%rbp), %eax
movl %eax, -0x8c(%rbp)
movl -0xa4(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xa4(%rbp)
movl -0x8c(%rbp), %eax
xorl %ecx, %ecx
subl -0x80(%rbp), %ecx
movl %ecx, %ecx
shlq %cl, %rax
addq -0x98(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
cmpq -0x30(%rbp), %rax
ja 0x17378
movl -0xa4(%rbp), %ecx
movq -0x28(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
movl -0x9c(%rbp), %eax
xorl %ecx, %ecx
subl -0x80(%rbp), %ecx
movl %ecx, %ecx
shlq %cl, %rax
movq %rax, -0xc0(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rax
movl (%rax), %esi
movq -0x58(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq -0xb8(%rbp), %r8
movq -0xc0(%rbp), %r9
callq 0x17770
jmp 0x1752f
movl -0x9c(%rbp), %eax
movl $0xa, %ecx
xorl %edx, %edx
divl %ecx
movl %eax, -0x9c(%rbp)
jmp 0x17262
movq -0x98(%rbp), %rax
cmpq -0x30(%rbp), %rax
jbe 0x173a1
jmp 0x173c0
leaq 0x68108(%rip), %rdi     # 0x7f4b0
leaq 0x67792(%rip), %rsi     # 0x7eb41
movl $0x3452, %edx           # imm = 0x3452
leaq 0x68076(%rip), %rcx     # 0x7f431
callq 0x6350
movl $0x0, -0xc4(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0xf8(%rbp)
callq 0x17900
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0xf8(%rbp), %rax
cmpq %rcx, %rax
ja 0x173f8
jmp 0x17417
leaq 0x680bc(%rip), %rdi     # 0x7f4bb
leaq 0x6773b(%rip), %rsi     # 0x7eb41
movl $0x345d, %edx           # imm = 0x345D
leaq 0x6801f(%rip), %rcx     # 0x7f431
callq 0x6350
imulq $0xa, -0x98(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
xorl %ecx, %ecx
subl -0x80(%rbp), %ecx
movl %ecx, %ecx
shrq %cl, %rax
movq %rax, -0xd0(%rbp)
movq -0x98(%rbp), %rax
movq -0x88(%rbp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, -0xd8(%rbp)
cmpq $0x9, -0xd0(%rbp)
ja 0x17466
jmp 0x17485
leaq 0x6803c(%rip), %rdi     # 0x7f4a9
leaq 0x676cd(%rip), %rsi     # 0x7eb41
movl $0x3466, %edx           # imm = 0x3466
leaq 0x67fb1(%rip), %rcx     # 0x7f431
callq 0x6350
movq -0xd0(%rbp), %rax
addq $0x30, %rax
movb %al, %dl
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movq -0xd8(%rbp), %rax
movq %rax, -0x98(%rbp)
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
imulq $0xa, -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
imulq $0xa, -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x98(%rbp), %rax
cmpq -0x30(%rbp), %rax
ja 0x174e7
jmp 0x174ec
jmp 0x173ca
movl -0xc4(%rbp), %edx
movq -0x28(%rbp), %rax
movl (%rax), %ecx
subl %edx, %ecx
movl %ecx, (%rax)
movq -0x88(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rax
movl (%rax), %esi
movq -0x58(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq -0x98(%rbp), %r8
movq -0xe0(%rbp), %r9
callq 0x17770
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopl (%rax,%rax)