#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ frexp(double, int *);
int modf(double, double *);
double pow10(int);
int ftoa(double f, char *bp) {
  int e, e1, e2, i;
  double digit, g, p;
  if (f >= 0)
    *bp++ = '+';
  else {
    f = -f;
    *bp++ = '-';
  }
  if (f == 0.)
    e = 1;
  else {
    frexp(f, &e);
    e = -e * 30103 / 100000;
    e1 = e / 2;
    e2 = e - e1;
    p = f * pow10(e2);
    while ((g = p * pow10(e1)) < 1.)
      e1++;
    while ((g = p * pow10(e1)) >= 10.)
      --e1;
    e = e1 + e2;
    f = g;
  }
  for (i = 0; i != 18; i++) {
    f = modf(f, &digit) * 10.;
    *bp++ = digit + '0';
  }
  *bp = '\0';
  return 1 - e;
}


x86 assembly (clang, -O0):
<ftoa>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
movsd  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     116a <ftoa+0x3a>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x2b,(%rax)
jmp    119d <ftoa+0x6d>
movsd  -0x8(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x2d,(%rax)
movsd  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11c1 <ftoa+0x91>
jp     11c1 <ftoa+0x91>
movl   $0x1,-0x14(%rbp)
jmp    12ba <ftoa+0x18a>
movsd  -0x8(%rbp),%xmm0
lea    -0x14(%rbp),%rdi
call   1050 <frexp@plt>
xor    %eax,%eax
sub    -0x14(%rbp),%eax
imul   $0x7597,%eax,%eax
mov    $0x186a0,%ecx
cltd
idiv   %ecx
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,-0x18(%rbp)
mov    -0x14(%rbp),%eax
sub    -0x18(%rbp),%eax
mov    %eax,-0x1c(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x1c(%rbp),%edi
call   1030 <pow10@plt>
movaps %xmm0,%xmm1
movsd  -0x40(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%edi
call   1030 <pow10@plt>
movsd  -0x48(%rbp),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,-0x30(%rbp)
movsd  0xdb9(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    125f <ftoa+0x12f>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    121f <ftoa+0xef>
jmp    1264 <ftoa+0x134>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%edi
call   1030 <pow10@plt>
movaps %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  0xd79(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     12a7 <ftoa+0x177>
mov    -0x18(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x18(%rbp)
jmp    1264 <ftoa+0x134>
mov    -0x18(%rbp),%eax
add    -0x1c(%rbp),%eax
mov    %eax,-0x14(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movl   $0x0,-0x20(%rbp)
cmpl   $0x12,-0x20(%rbp)
je     1324 <ftoa+0x1f4>
movsd  -0x8(%rbp),%xmm0
lea    -0x28(%rbp),%rdi
call   1040 <modf@plt>
cvtsi2sd %eax,%xmm0
movsd  0xd23(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xd15(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    12c1 <ftoa+0x191>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
mov    $0x1,%eax
sub    -0x14(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ftoa>:
push   %rbp
push   %r15
push   %r14
push   %rbx
sub    $0x28,%rsp
mov    %rdi,%r14
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
setb   %al
jae    1152 <ftoa+0x22>
xorpd  0xeae(%rip),%xmm0
add    %al,%al
add    $0x2b,%al
mov    %al,(%r14)
xor    %ebp,%ebp
ucomisd %xmm1,%xmm0
jne    1167 <ftoa+0x37>
jnp    120f <ftoa+0xdf>
lea    0xc(%rsp),%rdi
movapd %xmm0,0x10(%rsp)
call   1050 <frexp@plt>
imul   $0xffff8a69,0xc(%rsp),%eax
ff
cltq
imul   $0x14f8b589,%rax,%rbx
mov    %rbx,%r15
sar    $0x2d,%r15
mov    %rbx,%rbp
shr    $0x3f,%rbp
lea    (%r15,%rbp,1),%edi
sar    $0x2e,%rbx
add    %ebp,%ebx
sub    %ebx,%edi
call   1030 <pow10@plt>
movapd %xmm0,%xmm1
mulsd  0x10(%rsp),%xmm1
add    %r15d,%ebp
add    $0xffffffff,%ebp
movsd  %xmm1,0x10(%rsp)
nopl   (%rax)
mov    %ebx,%edi
call   1030 <pow10@plt>
movsd  0x10(%rsp),%xmm1
mulsd  %xmm1,%xmm0
add    $0x1,%ebx
add    $0x1,%ebp
movsd  0xe31(%rip),%xmm2
ucomisd %xmm0,%xmm2
ja     11c0 <ftoa+0x90>
add    $0xffffffff,%ebx
nopl   0x0(%rax,%rax,1)
mov    %ebx,%edi
call   1030 <pow10@plt>
mulsd  0x10(%rsp),%xmm0
add    $0xffffffff,%ebx
add    $0xffffffff,%ebp
ucomisd 0xe0d(%rip),%xmm0
jae    11f0 <ftoa+0xc0>
neg    %ebp
mov    $0x1,%ebx
lea    0x20(%rsp),%r15
nopl   0x0(%rax)
mov    %r15,%rdi
call   1040 <modf@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  0x20(%rsp),%xmm1
addsd  0xde3(%rip),%xmm1
cvttsd2si %xmm1,%eax
mulsd  0xdcf(%rip),%xmm0
mov    %al,(%r14,%rbx,1)
add    $0x1,%rbx
cmp    $0x13,%ebx
jne    1220 <ftoa+0xf0>
movb   $0x0,(%r14,%rbx,1)
mov    %ebp,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @ftoa(double %0, i8* %1) {
%3 = alloca double
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca double
%10 = alloca double
%11 = alloca double
store double %0, double* %3
store i8* %1, i8** %4
%12 = load double, double* %3
%13 = fcmp oge double %12, 0.000000e+00
br i1 %13, label %14, label %17
14: ; preds = %2
%15 = load i8*, i8** %4
%16 = getelementptr inbounds i8, i8* %15, i32 1
store i8* %16, i8** %4
store i8 43, i8* %15
br label %22
17: ; preds = %2
%18 = load double, double* %3
%19 = fneg double %18
store double %19, double* %3
%20 = load i8*, i8** %4
%21 = getelementptr inbounds i8, i8* %20, i32 1
store i8* %21, i8** %4
store i8 45, i8* %20
br label %22
22: ; preds = %17, %14
%23 = load double, double* %3
%24 = fcmp oeq double %23, 0.000000e+00
br i1 %24, label %25, label %26
25: ; preds = %22
store i32 1, i32* %5
br label %66
26: ; preds = %22
%27 = load double, double* %3
%28 = call i32 @frexp(double %27, i32* %5)
%29 = load i32, i32* %5
%30 = sub nsw i32 0, %29
%31 = mul nsw i32 %30, 30103
%32 = sdiv i32 %31, 100000
store i32 %32, i32* %5
%33 = load i32, i32* %5
%34 = sdiv i32 %33, 2
store i32 %34, i32* %6
%35 = load i32, i32* %5
%36 = load i32, i32* %6
%37 = sub nsw i32 %35, %36
store i32 %37, i32* %7
%38 = load double, double* %3
%39 = load i32, i32* %7
%40 = call double @pow10(i32 %39)
%41 = fmul double %38, %40
store double %41, double* %11
br label %42
42: ; preds = %48, %26
%43 = load double, double* %11
%44 = load i32, i32* %6
%45 = call double @pow10(i32 %44)
%46 = fmul double %43, %45
store double %46, double* %10
%47 = fcmp olt double %46, 1.000000e+00
br i1 %47, label %48, label %51
48: ; preds = %42
%49 = load i32, i32* %6
%50 = add nsw i32 %49, 1
store i32 %50, i32* %6
br label %42
51: ; preds = %42
br label %52
52: ; preds = %58, %51
%53 = load double, double* %11
%54 = load i32, i32* %6
%55 = call double @pow10(i32 %54)
%56 = fmul double %53, %55
store double %56, double* %10
%57 = fcmp oge double %56, 1.000000e+01
br i1 %57, label %58, label %61
58: ; preds = %52
%59 = load i32, i32* %6
%60 = add nsw i32 %59, -1
store i32 %60, i32* %6
br label %52
61: ; preds = %52
%62 = load i32, i32* %6
%63 = load i32, i32* %7
%64 = add nsw i32 %62, %63
store i32 %64, i32* %5
%65 = load double, double* %10
store double %65, double* %3
br label %66
66: ; preds = %61, %25
store i32 0, i32* %8
br label %67
67: ; preds = %80, %66
%68 = load i32, i32* %8
%69 = icmp ne i32 %68, 18
br i1 %69, label %70, label %83
70: ; preds = %67
%71 = load double, double* %3
%72 = call i32 @modf(double %71, double* %9)
%73 = sitofp i32 %72 to double
%74 = fmul double %73, 1.000000e+01
store double %74, double* %3
%75 = load double, double* %9
%76 = fadd double %75, 4.800000e+01
%77 = fptosi double %76 to i8
%78 = load i8*, i8** %4
%79 = getelementptr inbounds i8, i8* %78, i32 1
store i8* %79, i8** %4
store i8 %77, i8* %78
br label %80
80: ; preds = %70
%81 = load i32, i32* %8
%82 = add nsw i32 %81, 1
store i32 %82, i32* %8
br label %67
83: ; preds = %67
%84 = load i8*, i8** %4
store i8 0, i8* %84
%85 = load i32, i32* %5
%86 = sub nsw i32 1, %85
ret i32 %86
}

LLVM IR (-O2):
define i32 @ftoa(double %0, i8* nocapture writeonly %1) {
%3 = alloca i32
%4 = alloca double
%5 = bitcast i32* %3 to i8*
%6 = bitcast double* %4 to i8*
%7 = fcmp ult double %0, 0.000000e+00
%8 = fneg double %0
%9 = select i1 %7, i8 45, i8 43
%10 = select i1 %7, double %8, double %0
store i8 %9, i8* %1
%11 = fcmp oeq double %10, 0.000000e+00
br i1 %11, label %36, label %12
12: ; preds = %2
%13 = call i32 @frexp(double %10, i32* %3)
%14 = load i32, i32* %3
%15 = mul i32 %14, -30103
%16 = sdiv i32 %15, 100000
%17 = sdiv i32 %15, 200000
%18 = sub nsw i32 %16, %17
%19 = tail call double @pow10(i32 %18)
%20 = fmul double %10, %19
br label %21
21: ; preds = %21, %12
%22 = phi i32 [ %17, %12 ], [ %26, %21 ]
%23 = tail call double @pow10(i32 %22)
%24 = fmul double %20, %23
%25 = fcmp olt double %24, 1.000000e+00
%26 = add nsw i32 %22, 1
br i1 %25, label %21, label %27
27: ; preds = %21, %27
%28 = phi i32 [ %32, %27 ], [ %22, %21 ]
%29 = tail call double @pow10(i32 %28)
%30 = fmul double %20, %29
%31 = fcmp ult double %30, 1.000000e+01
%32 = add nsw i32 %28, -1
br i1 %31, label %33, label %27
33: ; preds = %27
%34 = add nsw i32 %28, %18
%35 = sub i32 1, %34
br label %36
36: ; preds = %2, %33
%37 = phi i32 [ %35, %33 ], [ 0, %2 ]
%38 = phi double [ %30, %33 ], [ %10, %2 ]
%39 = getelementptr inbounds i8, i8* %1, i64 1
br label %40
40: ; preds = %36, %40
%41 = phi i8* [ %39, %36 ], [ %51, %40 ]
%42 = phi double [ %38, %36 ], [ %46, %40 ]
%43 = phi i32 [ 0, %36 ], [ %50, %40 ]
%44 = call i32 @modf(double %42, double* %4)
%45 = sitofp i32 %44 to double
%46 = fmul double %45, 1.000000e+01
%47 = load double, double* %4
%48 = fadd double %47, 4.800000e+01
%49 = fptosi double %48 to i8
store i8 %49, i8* %41
%50 = add nuw nsw i32 %43, 1
%51 = getelementptr inbounds i8, i8* %41, i64 1
%52 = icmp eq i32 %50, 18
br i1 %52, label %53, label %40
53: ; preds = %40
store i8 0, i8* %51
ret i32 %37
}