#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 */
double frexp(double, int *);
void double_to_hex(double value, char *s) {
  double mant;
  int expon;
  int digit;
  char *p;
  char buf[12];
  static char hex[] = "0123456789ABCDEF";
  if (value < 0) {
    *s++ = '-';
    value = -value;
  }
  *s++ = '.';
  mant = frexp(value, &expon);
  if (mant == 0.0) {
    *s++ = '0';
  } else {
    while (mant > 0.0) {
      mant *= 16.0;
      digit = (int)mant;
      *s++ = hex[digit];
      mant -= ((double)digit);
    }
    if (expon != 0) {
      *s++ = 'x';
      if (expon < 0) {
        *s++ = '-';
        expon = -expon;
      }
      p = &buf[0];
      while (expon > 0) {
        *p++ = hex[expon & 0x0F];
        expon >>= 4;
      }
      while (p > &buf[0]) {
        *s++ = *--p;
      }
    }
  }
  *s++ = '\0';
}


x86 assembly (clang, -O0):
<double_to_hex>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x8(%rbp),%xmm0
jbe    1162 <double_to_hex+0x52>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x2d,(%rax)
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   $0x2e,(%rax)
movsd  -0x8(%rbp),%xmm0
lea    -0x1c(%rbp),%rdi
call   1030 <frexp@plt>
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11b6 <double_to_hex+0xa6>
jp     11b6 <double_to_hex+0xa6>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x30,(%rax)
jmp    12ea <double_to_hex+0x1da>
jmp    11bb <double_to_hex+0xab>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    121e <double_to_hex+0x10e>
movsd  0xe2b(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
cvttsd2si -0x18(%rbp),%eax
mov    %eax,-0x20(%rbp)
movslq -0x20(%rbp),%rcx
lea    0x2e3e(%rip),%rax
mov    (%rax,%rcx,1),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
cvtsi2sdl -0x20(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    11bb <double_to_hex+0xab>
cmpl   $0x0,-0x1c(%rbp)
je     12e5 <double_to_hex+0x1d5>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x78,(%rax)
cmpl   $0x0,-0x1c(%rbp)
jge    125e <double_to_hex+0x14e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x2d,(%rax)
xor    %eax,%eax
sub    -0x1c(%rbp),%eax
mov    %eax,-0x1c(%rbp)
lea    -0x34(%rbp),%rax
mov    %rax,-0x28(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jle    12a2 <double_to_hex+0x192>
mov    -0x1c(%rbp),%eax
and    $0xf,%eax
movslq %eax,%rcx
lea    0x2db0(%rip),%rax
mov    (%rax,%rcx,1),%cl
mov    -0x28(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x28(%rbp)
mov    %cl,(%rax)
mov    -0x1c(%rbp),%eax
sar    $0x4,%eax
mov    %eax,-0x1c(%rbp)
jmp    1266 <double_to_hex+0x156>
jmp    12a7 <double_to_hex+0x197>
mov    -0x28(%rbp),%rax
lea    -0x34(%rbp),%rcx
cmp    %rcx,%rax
jbe    12e0 <double_to_hex+0x1d0>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x28(%rbp)
mov    -0x1(%rax),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
jmp    12a7 <double_to_hex+0x197>
jmp    12e5 <double_to_hex+0x1d5>
jmp    12ea <double_to_hex+0x1da>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x0,(%rax)
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<double_to_hex>:
push   %rbx
sub    $0x10,%rsp
mov    %rdi,%rbx
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jbe    1131 <double_to_hex+0x21>
movb   $0x2d,(%rbx)
add    $0x1,%rbx
xorpd  0xecf(%rip),%xmm0
movb   $0x2e,(%rbx)
mov    %rsp,%rdi
call   1030 <frexp@plt>
ucomisd 0xed4(%rip),%xmm0
jne    1155 <double_to_hex+0x45>
jp     1155 <double_to_hex+0x45>
movb   $0x30,0x1(%rbx)
add    $0x2,%rbx
jmp    1333 <double_to_hex+0x223>
add    $0x1,%rbx
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    11a7 <double_to_hex+0x97>
movsd  0xea5(%rip),%xmm2
lea    0xeae(%rip),%rax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mulsd  %xmm2,%xmm0
cvttsd2si %xmm0,%ecx
movslq %ecx,%rcx
movzbl (%rcx,%rax,1),%ecx
mov    %cl,(%rbx)
cvttpd2dq %xmm0,%xmm3
cvtdq2pd %xmm3,%xmm3
add    $0x1,%rbx
subsd  %xmm3,%xmm0
ucomisd %xmm1,%xmm0
ja     1180 <double_to_hex+0x70>
cmpl   $0x0,(%rsp)
je     1333 <double_to_hex+0x223>
movb   $0x78,(%rbx)
mov    (%rsp),%edx
test   %edx,%edx
js     11c1 <double_to_hex+0xb1>
add    $0x1,%rbx
jmp    11ce <double_to_hex+0xbe>
movb   $0x2d,0x1(%rbx)
add    $0x2,%rbx
xor    %edx,%edx
sub    (%rsp),%edx
mov    %rbx,%r11
test   %edx,%edx
jle    123f <double_to_hex+0x12f>
lea    -0xc(%rsp),%rcx
mov    $0xfffffffffffffff0,%rsi
xor    %ebx,%ebx
lea    0xe36(%rip),%r8
xor    %edi,%edi
nopl   0x0(%rax)
mov    %edx,%eax
and    $0xf,%edx
movzbl (%rdx,%r8,1),%edx
mov    %dl,0x14(%rsp,%rsi,1)
mov    %eax,%edx
shr    $0x4,%edx
add    $0xffffffffffffffff,%rdi
add    $0x1,%rcx
add    $0x1,%rbx
add    $0x1,%rsi
cmp    $0x10,%eax
jae    11f0 <double_to_hex+0xe0>
mov    %edx,(%rsp)
lea    0x4(%rsp),%r10
mov    %r10,%rsi
sub    %rdi,%rsi
cmp    %r10,%rsi
jbe    123f <double_to_hex+0x12f>
mov    %rdi,%r8
neg    %r8
cmp    $0x20,%r8
jae    1247 <double_to_hex+0x137>
mov    %r11,%rbx
jmp    1320 <double_to_hex+0x210>
mov    %r11,%rbx
jmp    1333 <double_to_hex+0x223>
cmp    %rsi,%r11
jae    1263 <double_to_hex+0x153>
mov    %r11,%rax
sub    %rdi,%rax
lea    (%rsi,%rdi,1),%rdx
cmp    %rax,%rdx
jae    1263 <double_to_hex+0x153>
mov    %r11,%rbx
jmp    1320 <double_to_hex+0x210>
mov    %r8,%r9
and    $0xffffffffffffffe0,%r9
and    $0xffffffffffffffe0,%rbx
neg    %rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x4,%rsi
sub    %rdi,%rsi
lea    (%r11,%r9,1),%rbx
add    $0x10,%r11
mov    %r9,%rdi
neg    %rdi
xor    %edx,%edx
xorpd  %xmm0,%xmm0
movdqu -0x10(%rcx,%rdx,1),%xmm1
movdqu (%rcx,%rdx,1),%xmm2
movdqa %xmm2,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm3,%xmm2
movdqa %xmm1,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm3,%xmm1
movdqu %xmm2,-0x10(%r11)
movdqu %xmm1,(%r11)
add    $0x20,%r11
add    $0xffffffffffffffe0,%rdx
cmp    %rdx,%rdi
jne    1290 <double_to_hex+0x180>
cmp    %r9,%r8
je     1333 <double_to_hex+0x223>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl -0x1(%rsi),%eax
add    $0xffffffffffffffff,%rsi
mov    %al,(%rbx)
add    $0x1,%rbx
cmp    %r10,%rsi
ja     1320 <double_to_hex+0x210>
movb   $0x0,(%rbx)
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@double_to_hex.hex = internal global [17 x i8] c"0123456789ABCDEF\00"
define void @double_to_hex(double %0, i8* %1) {
%3 = alloca double
%4 = alloca i8*
%5 = alloca double
%6 = alloca i32
%7 = alloca i32
%8 = alloca i8*
%9 = alloca [12 x i8]
store double %0, double* %3
store i8* %1, i8** %4
%10 = load double, double* %3
%11 = fcmp olt double %10, 0.000000e+00
br i1 %11, label %12, label %17
12: ; preds = %2
%13 = load i8*, i8** %4
%14 = getelementptr inbounds i8, i8* %13, i32 1
store i8* %14, i8** %4
store i8 45, i8* %13
%15 = load double, double* %3
%16 = fneg double %15
store double %16, double* %3
br label %17
17: ; preds = %12, %2
%18 = load i8*, i8** %4
%19 = getelementptr inbounds i8, i8* %18, i32 1
store i8* %19, i8** %4
store i8 46, i8* %18
%20 = load double, double* %3
%21 = call double @frexp(double %20, i32* %6)
store double %21, double* %5
%22 = load double, double* %5
%23 = fcmp oeq double %22, 0.000000e+00
br i1 %23, label %24, label %27
24: ; preds = %17
%25 = load i8*, i8** %4
%26 = getelementptr inbounds i8, i8* %25, i32 1
store i8* %26, i8** %4
store i8 48, i8* %25
br label %87
27: ; preds = %17
br label %28
28: ; preds = %31, %27
%29 = load double, double* %5
%30 = fcmp ogt double %29, 0.000000e+00
br i1 %30, label %31, label %46
31: ; preds = %28
%32 = load double, double* %5
%33 = fmul double %32, 1.600000e+01
store double %33, double* %5
%34 = load double, double* %5
%35 = fptosi double %34 to i32
store i32 %35, i32* %7
%36 = load i32, i32* %7
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds [17 x i8], [17 x i8]* @double_to_hex.hex, i64 0, i64 %37
%39 = load i8, i8* %38
%40 = load i8*, i8** %4
%41 = getelementptr inbounds i8, i8* %40, i32 1
store i8* %41, i8** %4
store i8 %39, i8* %40
%42 = load i32, i32* %7
%43 = sitofp i32 %42 to double
%44 = load double, double* %5
%45 = fsub double %44, %43
store double %45, double* %5
br label %28
46: ; preds = %28
%47 = load i32, i32* %6
%48 = icmp ne i32 %47, 0
br i1 %48, label %49, label %86
49: ; preds = %46
%50 = load i8*, i8** %4
%51 = getelementptr inbounds i8, i8* %50, i32 1
store i8* %51, i8** %4
store i8 120, i8* %50
%52 = load i32, i32* %6
%53 = icmp slt i32 %52, 0
br i1 %53, label %54, label %59
54: ; preds = %49
%55 = load i8*, i8** %4
%56 = getelementptr inbounds i8, i8* %55, i32 1
store i8* %56, i8** %4
store i8 45, i8* %55
%57 = load i32, i32* %6
%58 = sub nsw i32 0, %57
store i32 %58, i32* %6
br label %59
59: ; preds = %54, %49
%60 = getelementptr inbounds [12 x i8], [12 x i8]* %9, i64 0, i64 0
store i8* %60, i8** %8
br label %61
61: ; preds = %64, %59
%62 = load i32, i32* %6
%63 = icmp sgt i32 %62, 0
br i1 %63, label %64, label %74
64: ; preds = %61
%65 = load i32, i32* %6
%66 = and i32 %65, 15
%67 = sext i32 %66 to i64
%68 = getelementptr inbounds [17 x i8], [17 x i8]* @double_to_hex.hex, i64 0, i64 %67
%69 = load i8, i8* %68
%70 = load i8*, i8** %8
%71 = getelementptr inbounds i8, i8* %70, i32 1
store i8* %71, i8** %8
store i8 %69, i8* %70
%72 = load i32, i32* %6
%73 = ashr i32 %72, 4
store i32 %73, i32* %6
br label %61
74: ; preds = %61
br label %75
75: ; preds = %79, %74
%76 = load i8*, i8** %8
%77 = getelementptr inbounds [12 x i8], [12 x i8]* %9, i64 0, i64 0
%78 = icmp ugt i8* %76, %77
br i1 %78, label %79, label %85
79: ; preds = %75
%80 = load i8*, i8** %8
%81 = getelementptr inbounds i8, i8* %80, i32 -1
store i8* %81, i8** %8
%82 = load i8, i8* %81
%83 = load i8*, i8** %4
%84 = getelementptr inbounds i8, i8* %83, i32 1
store i8* %84, i8** %4
store i8 %82, i8* %83
br label %75
85: ; preds = %75
br label %86
86: ; preds = %85, %46
br label %87
87: ; preds = %86, %24
%88 = load i8*, i8** %4
%89 = getelementptr inbounds i8, i8* %88, i32 1
store i8* %89, i8** %4
store i8 0, i8* %88
ret void
}

LLVM IR (-O2):
@double_to_hex.hex = internal unnamed_addr constant [17 x i8] c"0123456789ABCDEF\00"
define void @double_to_hex(double %0, i8* nocapture writeonly %1) {
%3 = alloca i32
%4 = alloca [12 x i8]
%5 = ptrtoint [12 x i8]* %4 to i64
%6 = bitcast i32* %3 to i8*
%7 = getelementptr inbounds [12 x i8], [12 x i8]* %4, i64 0, i64 0
%8 = fcmp olt double %0, 0.000000e+00
br i1 %8, label %9, label %12
9: ; preds = %2
%10 = getelementptr inbounds i8, i8* %1, i64 1
store i8 45, i8* %1
%11 = fneg double %0
br label %12
12: ; preds = %9, %2
%13 = phi i8* [ %10, %9 ], [ %1, %2 ]
%14 = phi double [ %11, %9 ], [ %0, %2 ]
%15 = getelementptr inbounds i8, i8* %13, i64 1
store i8 46, i8* %13
%16 = call double @frexp(double %14, i32* %3)
%17 = fcmp oeq double %16, 0.000000e+00
br i1 %17, label %20, label %18
18: ; preds = %12
%19 = fcmp ogt double %16, 0.000000e+00
br i1 %19, label %22, label %34
20: ; preds = %12
%21 = getelementptr inbounds i8, i8* %13, i64 2
store i8 48, i8* %15
br label %110
22: ; preds = %18, %22
%23 = phi double [ %32, %22 ], [ %16, %18 ]
%24 = phi i8* [ %30, %22 ], [ %15, %18 ]
%25 = fmul double %23, 1.600000e+01
%26 = fptosi double %25 to i32
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds [17 x i8], [17 x i8]* @double_to_hex.hex, i64 0, i64 %27
%29 = load i8, i8* %28
%30 = getelementptr inbounds i8, i8* %24, i64 1
store i8 %29, i8* %24
%31 = sitofp i32 %26 to double
%32 = fsub double %25, %31
%33 = fcmp ogt double %32, 0.000000e+00
br i1 %33, label %22, label %34
34: ; preds = %22, %18
%35 = phi i8* [ %15, %18 ], [ %30, %22 ]
%36 = load i32, i32* %3
%37 = icmp eq i32 %36, 0
br i1 %37, label %110, label %38
38: ; preds = %34
%39 = getelementptr inbounds i8, i8* %35, i64 1
store i8 120, i8* %35
%40 = load i32, i32* %3
%41 = icmp slt i32 %40, 0
br i1 %41, label %42, label %46
42: ; preds = %38
%43 = getelementptr inbounds i8, i8* %35, i64 2
store i8 45, i8* %39
%44 = load i32, i32* %3
%45 = sub nsw i32 0, %44
br label %46
46: ; preds = %42, %38
%47 = phi i32 [ %45, %42 ], [ %40, %38 ]
%48 = phi i8* [ %43, %42 ], [ %39, %38 ]
%49 = icmp sgt i32 %47, 0
br i1 %49, label %93, label %110
50: ; preds = %93
%51 = ptrtoint i8* %100 to i64
store i32 %101, i32* %3
%52 = icmp ugt i8* %100, %7
br i1 %52, label %53, label %110
53: ; preds = %50
%54 = sub i64 %51, %5
%55 = icmp ult i64 %54, 32
br i1 %55, label %90, label %56
56: ; preds = %53
%57 = sub i64 %51, %5
%58 = getelementptr i8, i8* %48, i64 %57
%59 = sub i64 %5, %51
%60 = getelementptr i8, i8* %100, i64 %59
%61 = icmp ult i8* %48, %100
%62 = icmp ult i8* %60, %58
%63 = and i1 %61, %62
br i1 %63, label %90, label %64
64: ; preds = %56
%65 = and i64 %54, -32
%66 = sub i64 0, %65
%67 = getelementptr i8, i8* %100, i64 %66
%68 = getelementptr i8, i8* %48, i64 %65
br label %69
69: ; preds = %69, %64
%70 = phi i64 [ 0, %64 ], [ %86, %69 ]
%71 = sub i64 0, %70
%72 = getelementptr i8, i8* %48, i64 %70
%73 = getelementptr inbounds i8, i8* %94, i64 %71
%74 = getelementptr inbounds i8, i8* %73, i64 -15
%75 = bitcast i8* %74 to <16 x i8>*
%76 = load <16 x i8>, <16 x i8>* %75
%77 = shufflevector <16 x i8> %76, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%78 = getelementptr inbounds i8, i8* %73, i64 -16
%79 = getelementptr inbounds i8, i8* %78, i64 -15
%80 = bitcast i8* %79 to <16 x i8>*
%81 = load <16 x i8>, <16 x i8>* %80
%82 = shufflevector <16 x i8> %81, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%83 = bitcast i8* %72 to <16 x i8>*
store <16 x i8> %77, <16 x i8>* %83
%84 = getelementptr i8, i8* %72, i64 16
%85 = bitcast i8* %84 to <16 x i8>*
store <16 x i8> %82, <16 x i8>* %85
%86 = add nuw i64 %70, 32
%87 = icmp eq i64 %86, %65
br i1 %87, label %88, label %69
88: ; preds = %69
%89 = icmp eq i64 %54, %65
br i1 %89, label %110, label %90
90: ; preds = %56, %53, %88
%91 = phi i8* [ %100, %56 ], [ %100, %53 ], [ %67, %88 ]
%92 = phi i8* [ %48, %56 ], [ %48, %53 ], [ %68, %88 ]
br label %103
93: ; preds = %46, %93
%94 = phi i8* [ %100, %93 ], [ %7, %46 ]
%95 = phi i32 [ %101, %93 ], [ %47, %46 ]
%96 = and i32 %95, 15
%97 = zext i32 %96 to i64
%98 = getelementptr inbounds [17 x i8], [17 x i8]* @double_to_hex.hex, i64 0, i64 %97
%99 = load i8, i8* %98
%100 = getelementptr inbounds i8, i8* %94, i64 1
store i8 %99, i8* %94
%101 = lshr i32 %95, 4
%102 = icmp ult i32 %95, 16
br i1 %102, label %50, label %93
103: ; preds = %90, %103
%104 = phi i8* [ %106, %103 ], [ %91, %90 ]
%105 = phi i8* [ %108, %103 ], [ %92, %90 ]
%106 = getelementptr inbounds i8, i8* %104, i64 -1
%107 = load i8, i8* %106
%108 = getelementptr inbounds i8, i8* %105, i64 1
store i8 %107, i8* %105
%109 = icmp ugt i8* %106, %7
br i1 %109, label %103, label %110
110: ; preds = %103, %88, %46, %50, %34, %20
%111 = phi i8* [ %21, %20 ], [ %35, %34 ], [ %48, %50 ], [ %48, %46 ], [ %68, %88 ], [ %108, %103 ]
store i8 0, i8* %111
ret void
}