// File: /workspace/github_c_makefile_star2_O2/BernardTatin[P]s7sh/s7.c
// Function: number_to_string_with_radix
static block_t *number_to_string_with_radix(s7_scheme *sc, s7_pointer obj, int32_t radix, s7_int width, s7_int precision, char float_choice, s7_int *nlen)
    {
        /* called by s7_number_to_string (char*), g_number_to_string (strp), number_to_string_p_pp (strp), format_number (strp basically) */
        /* the rest of s7 assumes nlen is set to the correct length */
        block_t *b;
        char *p;
        s7_int len, str_len;

#if WITH_GMP
        if (s7_is_bignum(obj))
        {
            p = big_number_to_string_with_radix(obj, radix, width, nlen, P_WRITE);
            b = string_to_block(sc, p, *nlen);
            free(p);
            return(b);
        }
        /* this ignores precision because it's way too hard to get the mpfr string to look like
         *   C's output -- we either have to call mpfr_get_str twice (the first time just to
         *   find out what the exponent is and how long the string actually is), or we have
         *   to do messy string manipulations.  So (format #f "",3F" pi) ignores the "3" and
         *   prints the full string.
         */
#endif

        if (radix == 10)
        {
            p = number_to_string_base_10(sc, obj, width, precision, float_choice, nlen, P_WRITE);
            return(string_to_block(sc, p, *nlen));
        }

        switch (type(obj))
        {
            case T_INTEGER:
                {
                    size_t len1;
                    b = mallocate(sc, (128 + width));
                    p = (char *)block_data(b);
                    len1 = integer_to_string_any_base(p, integer(obj), radix);
                    if ((size_t)width > len1)
                    {
                        size_t start;
                        start = width - len1;
                        memmove((void *)(p + start), (void *)p, len1);
                        memset((void *)p, (int)' ', start);
                        p[width] = '\0';
                        *nlen = width;
                    }
                    else *nlen = len1;
                    return(b);
                }

            case T_RATIO:
                {
                    size_t len1, len2;
                    str_len = 256 + width;
                    b = mallocate(sc, str_len);
                    p = (char *)block_data(b);
                    len1 = integer_to_string_any_base(p, numerator(obj), radix);
                    p[len1] = '/';
                    len2 = integer_to_string_any_base((char *)(p + len1 + 1), denominator(obj), radix);
                    len = len1 + 1 + len2;
                    p[len] = '\0';
                }
                break;

            case T_REAL:
                {
                    int32_t i;
                    s7_int int_part;
                    s7_double x, frac_part, min_frac, base;
                    bool sign = false;
                    char n[128], d[256];

                    x = real(obj);

                    if (is_NaN(x))
                        return(string_to_block(sc, "+nan.0", *nlen = 6));
                    if (is_inf(x))
                    {
                        if (x < 0.0)
                            return(string_to_block(sc, "-inf.0", *nlen = 6));
                        return(string_to_block(sc, "+inf.0", *nlen = 6));
                    }

                    if (x < 0.0)
                    {
                        sign = true;
                        x = -x;
                    }

                    if (x > 1.0e18) /* i.e. close to or greater than most-positive-fixnum (9.22e18), so the code below is unlikely to work, (format #f "~X" 1e19) */
                    {
                        int32_t ep;
                        block_t *b1;
                        len = 0;
                        ep = (int32_t)floor(log(x) / log((double)radix));
                        real(sc->real_wrapper3) = x / pow((double)radix, (double)ep); /* divide it down to one digit, then the fractional part */
                        b = number_to_string_with_radix(sc, sc->real_wrapper3, radix, width, precision, float_choice, &len);
                        b1 = mallocate(sc, len + 8);
                        p = (char *)block_data(b1);
                        p[0] = '\0';
                        (*nlen) = catstrs(p, len + 8, (sign) ? "-" : "", (char *)block_data(b), "e", integer_to_string_no_length(sc, ep), NULL);
                        liberate(sc, b);
                        return(b1);
                    }

                    int_part = (s7_int)floor(x);
                    frac_part = x - int_part;
                    integer_to_string_any_base(n, int_part, radix);
                    min_frac = dpow(radix, -precision);

                    /* doesn't this assume precision < 128/256 and that we can fit in 256 digits (1e308)? */
                    for (i = 0, base = radix; (i < precision) && (frac_part > min_frac); i++, base *= radix)
                    {
                        s7_int ipart;
                        ipart = (s7_int)(frac_part * base);
                        if (ipart >= radix)         /* rounding confusion */
                            ipart = radix - 1;
                        frac_part -= (ipart / base);
                        if (ipart < 10)
                            d[i] = (char)('0' + ipart);
                        else d[i] = (char)('a' + ipart -  10);
                    }
                    if (i == 0)
                        d[i++] = '0';
                    d[i] = '\0';
                    b = mallocate(sc, 256);
                    p = (char *)block_data(b);
                    p[0] = '\0';
                    len = catstrs(p, 256, (sign) ? "-" : "", n, ".", d, NULL);
                    str_len = 256;
                }
                break;

            default:
                {
                    block_t *n, *d;
                    char *dp;
                    real(sc->real_wrapper3) = real_part(obj);
                    n = number_to_string_with_radix(sc, sc->real_wrapper3, radix, 0, precision, float_choice, &len); /* include floatify */
                    real(sc->real_wrapper4) = imag_part(obj);
                    d = number_to_string_with_radix(sc, sc->real_wrapper4, radix, 0, precision, float_choice, &len);
                    dp = (char *)block_data(d);
                    b = mallocate(sc, 512);
                    p = (char *)block_data(b);
                    p[0] = '\0';
                    len = catstrs(p, 512, (char *)block_data(n), ((dp[0] == '+') || (dp[0] == '-')) ? "" : "+", dp, "i", NULL);
                    str_len = 512;
                    liberate(sc, n);
                    liberate(sc, d);
                }
                break;
        }

        if (width > len)
        {
            s7_int spaces;
            if (width >= str_len)
            {
                str_len = width + 1;
                b = reallocate(sc, b, str_len);
                p = (char *)block_data(b);
            }
            spaces = width - len;
            p[width] = '\0';
            memmove((void *)(p + spaces), (void *)p, len);
            memset((void *)p, (int)' ', spaces);
            (*nlen) = width;
        }
        else (*nlen) = len;
        return(b);
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1e8, %rsp            # imm = 0x1E8
movl %r9d, %r13d
movq %r8, %r12
movq %rcx, %r14
movq %rsi, %rbx
movq %rdi, %r15
movq 0x220(%rsp), %r9
cmpl $0xa, %edx
jne 0xc500
movsbl %r13b, %r8d
movq %r15, %rdi
movq %rbx, %rsi
movq %r14, %rdx
movq %r12, %rcx
movq %r9, %rbx
callq 0x730a4
movq (%rbx), %rdx
movq %r15, %rdi
movq %rax, %rsi
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x739d9
movl %edx, %ebp
movzbl (%rbx), %eax
cmpl $0xd, %eax
movq %r9, 0x18(%rsp)
je 0xc5e0
cmpl $0xc, %eax
je 0xc577
cmpl $0xb, %eax
jne 0xc62d
leaq 0x80(%r14), %rsi
movq %r15, %rdi
callq 0x9037
movq %rax, %r12
movq (%rax), %r15
movq 0x8(%rbx), %rsi
movq %r15, %rdi
movl %ebp, %edx
callq 0x73a18
movq %r14, %rbx
subq %rax, %rbx
jbe 0xc77d
leaq (%r15,%rbx), %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x8550
pushq $0x20
popq %rsi
movq %r15, %rdi
movq %rbx, %rdx
callq 0x8270
movb $0x0, (%r15,%r14)
jmp 0xc780
leaq 0x100(%r14), %rsi
movq %r15, %rdi
movq %rsi, 0x20(%rsp)
callq 0x9037
movq %r14, 0x30(%rsp)
movq %rax, %r14
movq (%rax), %r13
movq 0x8(%rbx), %rsi
movq %r13, %rdi
movl %ebp, %edx
callq 0x73a18
movq %rax, %r12
leaq (%rax,%r13), %rdi
incq %rdi
movb $0x2f, -0x1(%rdi)
movq 0x10(%rbx), %rsi
movl %ebp, %edx
callq 0x73a18
leaq (%r12,%rax), %rcx
leaq (%r12,%rax), %rbp
incq %rbp
movq %r14, %r12
movq 0x30(%rsp), %r14
movq %rbp, 0x10(%rsp)
movb $0x0, 0x1(%r13,%rcx)
jmp 0xc728
movsd 0x8(%rbx), %xmm1
ucomisd %xmm1, %xmm1
jp 0xca20
movq %xmm1, %rax
btrq $0x3f, %rax
movabsq $0x7ff0000000000000, %rcx # imm = 0x7FF0000000000000
cmpq %rcx, %rax
jne 0xc79d
xorpd %xmm0, %xmm0
ucomisd %xmm1, %xmm0
movq $0x6, (%r9)
jbe 0xc8df
leaq 0xd5fc6(%rip), %rsi     # 0xe25ee
jmp 0xc8e6
movsd 0x8(%rbx), %xmm0
movq 0x1f28(%r15), %rax
movsd %xmm0, 0x8(%rax)
movq 0x1f28(%r15), %rsi
leaq 0x10(%rsp), %rax
movq %rax, (%rsp)
movsbl %r13b, %r13d
movq %r15, %rdi
movl %ebp, %edx
xorl %ecx, %ecx
movq %r12, %r8
movl %r13d, %r9d
callq 0xc49c
movq %rax, 0x40(%rsp)
movsd 0x10(%rbx), %xmm0
movq 0x1f30(%r15), %rax
movsd %xmm0, 0x8(%rax)
movq 0x1f30(%r15), %rsi
leaq 0x10(%rsp), %rax
movq %rax, (%rsp)
movq %r15, %rdi
movl %ebp, %edx
xorl %ecx, %ecx
movq %r12, %r8
movl %r13d, %r9d
callq 0xc49c
movq %rax, 0x30(%rsp)
movq (%rax), %rbp
movl $0x200, %eax            # imm = 0x200
movq %rax, 0x20(%rsp)
movl $0x200, %esi            # imm = 0x200
movq %r15, %rdi
callq 0x9037
movq %rax, %r12
movq (%rax), %r13
movb $0x0, (%r13)
movq 0x40(%rsp), %rbx
movq (%rbx), %rdx
movb (%rbp), %al
addb $-0x2b, %al
leaq 0xdbd94(%rip), %rsi     # 0xe846e
leaq 0xd4143(%rip), %rcx     # 0xe0824
testb $-0x3, %al
cmoveq %rsi, %rcx
andq $0x0, (%rsp)
leaq 0xd9e29(%rip), %r9      # 0xe651c
movl $0x200, %esi            # imm = 0x200
movq %r13, %rdi
movq %rbp, %r8
xorl %eax, %eax
callq 0x90f7
movq %rax, %rbp
leaq 0x10(%rsp), %rax
movq %rbp, (%rax)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x9439
movq %r15, %rdi
movq 0x30(%rsp), %rsi
callq 0x9439
movq %r14, %rbx
subq %rbp, %rbx
movq 0x18(%rsp), %rax
jle 0xc778
cmpq %r14, 0x20(%rsp)
jg 0xc751
leaq 0x1(%r14), %rdx
movq %r15, %rdi
movq %r12, %rsi
callq 0x9859
movq %rax, %r12
movq (%rax), %r13
movb $0x0, (%r13,%r14)
leaq (%rbx,%r13), %rdi
movq 0x10(%rsp), %rdx
movq %r13, %rsi
callq 0x8550
pushq $0x20
popq %rsi
movq %r13, %rdi
movq %rbx, %rdx
callq 0x8270
jmp 0xc780
movq %rbp, %r14
jmp 0xc785
movq %rax, %r14
movq 0x18(%rsp), %rax
movq %r14, (%rax)
movq %r12, %rax
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movapd 0xc970b(%rip), %xmm0    # 0xd5eb0
xorpd %xmm1, %xmm0
maxsd %xmm1, %xmm0
ucomisd 0xc5883(%rip), %xmm0    # 0xd2038
movaps %xmm1, 0x30(%rsp)
movapd %xmm0, 0x20(%rsp)
jbe 0xc8f9
leaq 0x10(%rsp), %rbx
andq $0x0, (%rbx)
callq 0x82b0
movsd %xmm0, 0x40(%rsp)
cvtsi2sd %ebp, %xmm0
movsd %xmm0, 0x58(%rsp)
callq 0x82b0
movsd 0x40(%rsp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
callq 0x85f0
movapd %xmm0, 0x40(%rsp)
cvttpd2dq %xmm0, %xmm1
cvtdq2pd %xmm1, %xmm1
movsd 0x58(%rsp), %xmm0
callq 0x8160
movapd 0x20(%rsp), %xmm1
divsd %xmm0, %xmm1
movq 0x1f28(%r15), %rax
movsd %xmm1, 0x8(%rax)
movq 0x1f28(%r15), %rsi
movq %rbx, (%rsp)
movsbl %r13b, %r9d
movq %r15, %rdi
movl %ebp, %edx
movq %r14, %rcx
movq %r12, %r8
callq 0xc49c
movq %rax, %rbp
movq (%rbx), %r14
addq $0x8, %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x9037
xorpd %xmm0, %xmm0
ucomisd 0x30(%rsp), %xmm0
movq %rax, %rbx
cvttsd2si 0x40(%rsp), %eax
leaq 0xd9c92(%rip), %rcx     # 0xe650b
leaq 0xdbbee(%rip), %r12     # 0xe846e
cmovaq %rcx, %r12
movq (%rbx), %r13
movb $0x0, (%r13)
movq (%rbp), %rcx
movq %rcx, 0x20(%rsp)
movslq %eax, %rsi
movq %r15, %rdi
callq 0x73af1
andq $0x0, (%rsp)
leaq 0xd5d58(%rip), %r8      # 0xe2604
movq %r13, %rdi
movq %r14, %rsi
movq %r12, %rdx
movq %rbx, %r12
movq 0x20(%rsp), %rcx
movq %rax, %r9
xorl %eax, %eax
callq 0x90f7
movq 0x18(%rsp), %rcx
movq %rax, (%rcx)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x9439
jmp 0xc788
leaq 0xd5d0f(%rip), %rsi     # 0xe25f5
pushq $0x6
popq %rdx
movq %r15, %rdi
callq 0x739d9
movq %rax, %r12
jmp 0xc788
callq 0x85f0
cvttsd2si %xmm0, %rsi
cvtsi2sd %rsi, %xmm0
movapd 0x20(%rsp), %xmm1
subsd %xmm0, %xmm1
movapd %xmm1, 0x20(%rsp)
leaq 0x160(%rsp), %rdi
movl %ebp, %edx
callq 0x73a18
movl %r12d, %esi
negl %esi
movl %ebp, %edi
callq 0x73b57
movapd 0x20(%rsp), %xmm4
cvtsi2sd %ebp, %xmm1
movslq %ebp, %rcx
decl %ebp
movslq %ebp, %rdx
xorl %eax, %eax
pushq $0x30
popq %rsi
pushq $0x57
popq %rdi
movapd %xmm1, %xmm2
cmpq %r12, %rax
jge 0xc999
ucomisd %xmm0, %xmm4
jbe 0xc999
movapd %xmm4, %xmm3
mulsd %xmm2, %xmm3
cvttsd2si %xmm3, %r8
cmpq %rcx, %r8
cmovgeq %rdx, %r8
cvtsi2sd %r8, %xmm3
divsd %xmm2, %xmm3
subsd %xmm3, %xmm4
cmpq $0xa, %r8
movl %edi, %r9d
cmovll %esi, %r9d
addb %r8b, %r9b
movb %r9b, 0x60(%rsp,%rax)
incq %rax
mulsd %xmm1, %xmm2
jmp 0xc951
testq %rax, %rax
jne 0xc9a6
movb $0x30, 0x60(%rsp,%rax)
pushq $0x1
popq %rax
movl %eax, %eax
xorl %ebx, %ebx
movb %bl, 0x60(%rsp,%rax)
movl $0x100, %eax            # imm = 0x100
movq %rax, 0x20(%rsp)
movl $0x100, %esi            # imm = 0x100
movq %r15, %rdi
callq 0x9037
xorpd %xmm0, %xmm0
ucomisd 0x30(%rsp), %xmm0
movq %rax, %r12
movq (%rax), %r13
movb %bl, (%r13)
leaq 0xd9b2b(%rip), %rax     # 0xe650b
leaq 0xdba87(%rip), %rdx     # 0xe846e
cmovaq %rax, %rdx
andq $0x0, (%rsp)
leaq 0xd131a(%rip), %r8      # 0xddd11
leaq 0x160(%rsp), %rcx
leaq 0x60(%rsp), %r9
movl $0x100, %esi            # imm = 0x100
movq %r13, %rdi
xorl %eax, %eax
callq 0x90f7
movq %rax, %rbp
movq %rax, 0x10(%rsp)
jmp 0xc728
movq $0x6, (%r9)
leaq 0xd5bb9(%rip), %rsi     # 0xe25e7
jmp 0xc8e6