#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 atof(const char *num) {
  if (!num || !*num)
    return 0;
  double integerPart = 0;
  double fractionPart = 0;
  int divisorForFraction = 1;
  int sign = 1;
  bool inFraction = false;
  if (*num == '-') {
    ++num;
    sign = -1;
  } else if (*num == '+') {
    ++num;
  }
  while (*num != '\0') {
    if (*num >= '0' && *num <= '9') {
      if (inFraction) {
        fractionPart = fractionPart * 10 + (*num - '0');
        divisorForFraction *= 10;
      } else {
        integerPart = integerPart * 10 + (*num - '0');
      }
    } else if (*num == '.') {
      if (inFraction)
        return sign * (integerPart + fractionPart / divisorForFraction);
      else
        inFraction = true;
    } else {
      return sign * (integerPart + fractionPart / divisorForFraction);
    }
    ++num;
  }
  return sign * (integerPart + fractionPart / divisorForFraction);
}


x86 assembly (clang, -O0):
<atof>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     1120 <atof+0x20>
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
jne    112d <atof+0x2d>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f0 <atof+0x1f0>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x1,-0x24(%rbp)
movl   $0x1,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
jne    117a <atof+0x7a>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
movl   $0xffffffff,-0x28(%rbp)
jmp    119b <atof+0x9b>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2b,%eax
jne    1196 <atof+0x96>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    119b <atof+0x9b>
jmp    11a0 <atof+0xa0>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     12cb <atof+0x1cb>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     123b <atof+0x13b>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jg     123b <atof+0x13b>
cmpl   $0x0,-0x2c(%rbp)
je     120e <atof+0x10e>
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
sub    $0x30,%eax
cvtsi2sd %eax,%xmm1
movsd  0xe0b(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
imul   $0xa,-0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    1236 <atof+0x136>
movsd  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
sub    $0x30,%eax
cvtsi2sd %eax,%xmm1
movsd  0xdd7(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    12ba <atof+0x1ba>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    128b <atof+0x18b>
cmpl   $0x0,-0x2c(%rbp)
je     127f <atof+0x17f>
cvtsi2sdl -0x28(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
cvtsi2sdl -0x24(%rbp),%xmm3
divsd  %xmm3,%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f0 <atof+0x1f0>
movl   $0x1,-0x2c(%rbp)
jmp    12b5 <atof+0x1b5>
cvtsi2sdl -0x28(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
cvtsi2sdl -0x24(%rbp),%xmm3
divsd  %xmm3,%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f0 <atof+0x1f0>
jmp    12ba <atof+0x1ba>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    11a0 <atof+0xa0>
cvtsi2sdl -0x28(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
cvtsi2sdl -0x24(%rbp),%xmm3
divsd  %xmm3,%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<atof>:
xorpd  %xmm0,%xmm0
test   %rdi,%rdi
je     11ea <atof+0xea>
mov    (%rdi),%cl
test   %cl,%cl
je     11ea <atof+0xea>
cmp    $0x2d,%cl
je     11b3 <atof+0xb3>
movsd  0xee0(%rip),%xmm0
cmp    $0x2b,%cl
je     11bb <atof+0xbb>
test   %cl,%cl
je     11ca <atof+0xca>
add    $0x1,%rdi
xorpd  %xmm1,%xmm1
mov    $0x1,%eax
xor    %edx,%edx
movsd  0xec0(%rip),%xmm3
xorpd  %xmm2,%xmm2
jmp    118e <atof+0x8e>
cs nopw 0x0(%rax,%rax,1)
movsbl %cl,%ecx
add    $0xffffffd0,%ecx
xorps  %xmm4,%xmm4
cvtsi2sd %ecx,%xmm4
test   %edx,%edx
je     11a7 <atof+0xa7>
mulsd  %xmm3,%xmm1
addsd  %xmm4,%xmm1
add    %eax,%eax
lea    (%rax,%rax,4),%eax
mov    $0x1,%edx
movzbl (%rdi),%ecx
add    $0x1,%rdi
test   %cl,%cl
je     11d7 <atof+0xd7>
lea    -0x30(%rcx),%esi
cmp    $0x9,%sil
jbe    1160 <atof+0x60>
test   %edx,%edx
jne    11d7 <atof+0xd7>
mov    $0x1,%edx
cmp    $0x2e,%cl
je     1183 <atof+0x83>
jmp    11d7 <atof+0xd7>
mulsd  %xmm3,%xmm2
addsd  %xmm4,%xmm2
xor    %edx,%edx
jmp    1183 <atof+0x83>
movsd  0xe45(%rip),%xmm0
mov    0x1(%rdi),%cl
add    $0x1,%rdi
test   %cl,%cl
jne    1139 <atof+0x39>
mov    $0x1,%eax
xorpd  %xmm2,%xmm2
xorpd  %xmm1,%xmm1
xorps  %xmm3,%xmm3
cvtsi2sd %eax,%xmm3
divsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @atof(i8* %0) {
%2 = alloca double
%3 = alloca i8*
%4 = alloca double
%5 = alloca double
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i8* %0, i8** %3
%9 = load i8*, i8** %3
%10 = icmp ne i8* %9, null
br i1 %10, label %11, label %15
11: ; preds = %1
%12 = load i8*, i8** %3
%13 = load i8, i8* %12
%14 = icmp ne i8 %13, 0
br i1 %14, label %16, label %15
15: ; preds = %11, %1
store double 0.000000e+00, double* %2
br label %115
16: ; preds = %11
store double 0.000000e+00, double* %4
store double 0.000000e+00, double* %5
store i32 1, i32* %6
store i32 1, i32* %7
store i32 0, i32* %8
%17 = load i8*, i8** %3
%18 = load i8, i8* %17
%19 = sext i8 %18 to i32
%20 = icmp eq i32 %19, 45
br i1 %20, label %21, label %24
21: ; preds = %16
%22 = load i8*, i8** %3
%23 = getelementptr inbounds i8, i8* %22, i32 1
store i8* %23, i8** %3
store i32 -1, i32* %7
br label %33
24: ; preds = %16
%25 = load i8*, i8** %3
%26 = load i8, i8* %25
%27 = sext i8 %26 to i32
%28 = icmp eq i32 %27, 43
br i1 %28, label %29, label %32
29: ; preds = %24
%30 = load i8*, i8** %3
%31 = getelementptr inbounds i8, i8* %30, i32 1
store i8* %31, i8** %3
br label %32
32: ; preds = %29, %24
br label %33
33: ; preds = %32, %21
br label %34
34: ; preds = %102, %33
%35 = load i8*, i8** %3
%36 = load i8, i8* %35
%37 = sext i8 %36 to i32
%38 = icmp ne i32 %37, 0
br i1 %38, label %39, label %105
39: ; preds = %34
%40 = load i8*, i8** %3
%41 = load i8, i8* %40
%42 = sext i8 %41 to i32
%43 = icmp sge i32 %42, 48
br i1 %43, label %44, label %71
44: ; preds = %39
%45 = load i8*, i8** %3
%46 = load i8, i8* %45
%47 = sext i8 %46 to i32
%48 = icmp sle i32 %47, 57
br i1 %48, label %49, label %71
49: ; preds = %44
%50 = load i32, i32* %8
%51 = icmp ne i32 %50, 0
br i1 %51, label %52, label %62
52: ; preds = %49
%53 = load double, double* %5
%54 = load i8*, i8** %3
%55 = load i8, i8* %54
%56 = sext i8 %55 to i32
%57 = sub nsw i32 %56, 48
%58 = sitofp i32 %57 to double
%59 = call double @llvm.fmuladd.f64(double %53, double 1.000000e+01, double %58)
store double %59, double* %5
%60 = load i32, i32* %6
%61 = mul nsw i32 %60, 10
store i32 %61, i32* %6
br label %70
62: ; preds = %49
%63 = load double, double* %4
%64 = load i8*, i8** %3
%65 = load i8, i8* %64
%66 = sext i8 %65 to i32
%67 = sub nsw i32 %66, 48
%68 = sitofp i32 %67 to double
%69 = call double @llvm.fmuladd.f64(double %63, double 1.000000e+01, double %68)
store double %69, double* %4
br label %70
70: ; preds = %62, %52
br label %102
71: ; preds = %44, %39
%72 = load i8*, i8** %3
%73 = load i8, i8* %72
%74 = sext i8 %73 to i32
%75 = icmp eq i32 %74, 46
br i1 %75, label %76, label %91
76: ; preds = %71
%77 = load i32, i32* %8
%78 = icmp ne i32 %77, 0
br i1 %78, label %79, label %89
79: ; preds = %76
%80 = load i32, i32* %7
%81 = sitofp i32 %80 to double
%82 = load double, double* %4
%83 = load double, double* %5
%84 = load i32, i32* %6
%85 = sitofp i32 %84 to double
%86 = fdiv double %83, %85
%87 = fadd double %82, %86
%88 = fmul double %81, %87
store double %88, double* %2
br label %115
89: ; preds = %76
store i32 1, i32* %8
br label %90
90: ; preds = %89
br label %101
91: ; preds = %71
%92 = load i32, i32* %7
%93 = sitofp i32 %92 to double
%94 = load double, double* %4
%95 = load double, double* %5
%96 = load i32, i32* %6
%97 = sitofp i32 %96 to double
%98 = fdiv double %95, %97
%99 = fadd double %94, %98
%100 = fmul double %93, %99
store double %100, double* %2
br label %115
101: ; preds = %90
br label %102
102: ; preds = %101, %70
%103 = load i8*, i8** %3
%104 = getelementptr inbounds i8, i8* %103, i32 1
store i8* %104, i8** %3
br label %34
105: ; preds = %34
%106 = load i32, i32* %7
%107 = sitofp i32 %106 to double
%108 = load double, double* %4
%109 = load double, double* %5
%110 = load i32, i32* %6
%111 = sitofp i32 %110 to double
%112 = fdiv double %109, %111
%113 = fadd double %108, %112
%114 = fmul double %107, %113
store double %114, double* %2
br label %115
115: ; preds = %105, %91, %79, %15
%116 = load double, double* %2
ret double %116
}

LLVM IR (-O2):
define double @atof(i8* %0) {
%2 = icmp eq i8* %0, null
br i1 %2, label %54, label %3
3: ; preds = %1
%4 = load i8, i8* %0
switch i8 %4, label %10 [
i8 0, label %54
i8 45, label %6
i8 43, label %5
]
5: ; preds = %3
br label %6
6: ; preds = %3, %5
%7 = phi double [ 1.000000e+00, %5 ], [ -1.000000e+00, %3 ]
%8 = getelementptr inbounds i8, i8* %0, i64 1
%9 = load i8, i8* %8
br label %10
10: ; preds = %6, %3
%11 = phi i8 [ %9, %6 ], [ %4, %3 ]
%12 = phi i8* [ %8, %6 ], [ %0, %3 ]
%13 = phi double [ %7, %6 ], [ 1.000000e+00, %3 ]
%14 = icmp eq i8 %11, 0
br i1 %14, label %46, label %15
15: ; preds = %10, %38
%16 = phi i8 [ %44, %38 ], [ %11, %10 ]
%17 = phi i32 [ %42, %38 ], [ 0, %10 ]
%18 = phi i32 [ %41, %38 ], [ 1, %10 ]
%19 = phi double [ %40, %38 ], [ 0.000000e+00, %10 ]
%20 = phi double [ %39, %38 ], [ 0.000000e+00, %10 ]
%21 = phi i8* [ %43, %38 ], [ %12, %10 ]
%22 = add i8 %16, -48
%23 = icmp ult i8 %22, 10
br i1 %23, label %24, label %34
24: ; preds = %15
%25 = sext i8 %16 to i32
%26 = icmp eq i32 %17, 0
%27 = add nsw i32 %25, -48
%28 = sitofp i32 %27 to double
br i1 %26, label %32, label %29
29: ; preds = %24
%30 = tail call double @llvm.fmuladd.f64(double %19, double 1.000000e+01, double %28)
%31 = mul nsw i32 %18, 10
br label %38
32: ; preds = %24
%33 = tail call double @llvm.fmuladd.f64(double %20, double 1.000000e+01, double %28)
br label %38
34: ; preds = %15
%35 = icmp eq i8 %16, 46
%36 = icmp eq i32 %17, 0
%37 = and i1 %36, %35
br i1 %37, label %38, label %46
38: ; preds = %34, %29, %32
%39 = phi double [ %20, %29 ], [ %33, %32 ], [ %20, %34 ]
%40 = phi double [ %30, %29 ], [ %19, %32 ], [ %19, %34 ]
%41 = phi i32 [ %31, %29 ], [ %18, %32 ], [ %18, %34 ]
%42 = phi i32 [ 1, %29 ], [ 0, %32 ], [ 1, %34 ]
%43 = getelementptr inbounds i8, i8* %21, i64 1
%44 = load i8, i8* %43
%45 = icmp eq i8 %44, 0
br i1 %45, label %46, label %15
46: ; preds = %34, %38, %10
%47 = phi double [ 0.000000e+00, %10 ], [ %39, %38 ], [ %20, %34 ]
%48 = phi double [ 0.000000e+00, %10 ], [ %40, %38 ], [ %19, %34 ]
%49 = phi i32 [ 1, %10 ], [ %41, %38 ], [ %18, %34 ]
%50 = sitofp i32 %49 to double
%51 = fdiv double %48, %50
%52 = fadd double %47, %51
%53 = fmul double %13, %52
br label %54
54: ; preds = %3, %1, %46
%55 = phi double [ %53, %46 ], [ 0.000000e+00, %3 ], [ 0.000000e+00, %1 ]
ret double %55
}