long read_float_10E3(const char *string) {
  unsigned long result = 0;
  if (*string < '0' || *string > '9')
    return -1;
  do
    result = result * 10 + *string - '0';
  while (*++string >= '0' && *string <= '9');
  if (!*string)
    return result * 1000;
  if (*string != '.')
    return -1;
  ++string;
  if (*string < '0' || *string > '9')
    return -1;
  result = result * 10 + *string - '0';
  ++string;
  if (!*string)
    return result * 100;
  if (*string < '0' || *string > '9')
    return -1;
  result = result * 10 + *string - '0';
  ++string;
  if (!*string)
    return result * 10;
  if (*string < '0' || *string > '9')
    return -1;
  result = result * 10 + *string - '0';
  ++string;
  if (!*string)
    return result;
  return -1;
}


x86 assembly (clang, -O0):
<read_float_10E3>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     1130 <read_float_10E3+0x30>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jle    113d <read_float_10E3+0x3d>
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
jmp    1328 <read_float_10E3+0x228>
jmp    1142 <read_float_10E3+0x42>
imul   $0xa,-0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
movsbq (%rcx),%rcx
add    %rcx,%rax
sub    $0x30,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl 0x1(%rax),%ecx
xor    %eax,%eax
cmp    $0x30,%ecx
mov    %al,-0x19(%rbp)
jl     118b <read_float_10E3+0x8b>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
setle  %al
mov    %al,-0x19(%rbp)
mov    -0x19(%rbp),%al
test   $0x1,%al
jne    1142 <read_float_10E3+0x42>
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
jne    11b4 <read_float_10E3+0xb4>
imul   $0x3e8,-0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1328 <read_float_10E3+0x228>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
je     11d1 <read_float_10E3+0xd1>
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
jmp    1328 <read_float_10E3+0x228>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     11fd <read_float_10E3+0xfd>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jle    120a <read_float_10E3+0x10a>
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
jmp    1328 <read_float_10E3+0x228>
imul   $0xa,-0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
movsbq (%rcx),%rcx
add    %rcx,%rax
sub    $0x30,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
jne    1249 <read_float_10E3+0x149>
imul   $0x64,-0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1328 <read_float_10E3+0x228>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     1269 <read_float_10E3+0x169>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jle    1276 <read_float_10E3+0x176>
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
jmp    1328 <read_float_10E3+0x228>
imul   $0xa,-0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
movsbq (%rcx),%rcx
add    %rcx,%rax
sub    $0x30,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
jne    12b5 <read_float_10E3+0x1b5>
imul   $0xa,-0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1328 <read_float_10E3+0x228>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     12d5 <read_float_10E3+0x1d5>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jle    12e2 <read_float_10E3+0x1e2>
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
jmp    1328 <read_float_10E3+0x228>
imul   $0xa,-0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
movsbq (%rcx),%rcx
add    %rcx,%rax
sub    $0x30,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
jne    1320 <read_float_10E3+0x220>
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1328 <read_float_10E3+0x228>
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<read_float_10E3>:
mov    (%rdi),%dl
lea    -0x3a(%rdx),%ecx
mov    $0xffffffffffffffff,%rax
cmp    $0xf6,%cl
jb     11aa <read_float_10E3+0xaa>
add    $0x1,%rdi
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
lea    (%rcx,%rcx,4),%rcx
movzbl %dl,%edx
lea    (%rdx,%rcx,2),%rcx
add    $0xffffffffffffffd0,%rcx
movzbl (%rdi),%edx
lea    -0x30(%rdx),%esi
add    $0x1,%rdi
cmp    $0xa,%sil
jb     1120 <read_float_10E3+0x20>
cmp    $0x2e,%dl
je     1150 <read_float_10E3+0x50>
test   %dl,%dl
jne    11aa <read_float_10E3+0xaa>
imul   $0x3e8,%rcx,%rax
ret
movzbl (%rdi),%edx
lea    -0x3a(%rdx),%esi
cmp    $0xf6,%sil
jb     11aa <read_float_10E3+0xaa>
lea    (%rcx,%rcx,4),%rcx
lea    (%rdx,%rcx,2),%rcx
add    $0xffffffffffffffd0,%rcx
movzbl 0x1(%rdi),%edx
test   %rdx,%rdx
je     11ab <read_float_10E3+0xab>
lea    -0x3a(%rdx),%esi
cmp    $0xf6,%sil
jb     11aa <read_float_10E3+0xaa>
lea    (%rcx,%rcx,4),%rcx
lea    (%rdx,%rcx,2),%rcx
add    $0xffffffffffffffd0,%rcx
movzbl 0x2(%rdi),%edx
test   %rdx,%rdx
je     11b0 <read_float_10E3+0xb0>
lea    -0x3a(%rdx),%esi
cmp    $0xf6,%sil
jb     11aa <read_float_10E3+0xaa>
cmpb   $0x0,0x3(%rdi)
jne    11aa <read_float_10E3+0xaa>
lea    (%rcx,%rcx,4),%rax
lea    (%rdx,%rax,2),%rax
add    $0xffffffffffffffd0,%rax
ret
imul   $0x64,%rcx,%rax
ret
add    %rcx,%rcx
lea    (%rcx,%rcx,4),%rax
ret

LLVM IR (-O0):
define i64 @read_float_10E3(i8* %0) {
%2 = alloca i64
%3 = alloca i8*
%4 = alloca i64
store i8* %0, i8** %3
store i64 0, i64* %4
%5 = load i8*, i8** %3
%6 = load i8, i8* %5
%7 = sext i8 %6 to i32
%8 = icmp slt i32 %7, 48
br i1 %8, label %14, label %9
9: ; preds = %1
%10 = load i8*, i8** %3
%11 = load i8, i8* %10
%12 = sext i8 %11 to i32
%13 = icmp sgt i32 %12, 57
br i1 %13, label %14, label %15
14: ; preds = %9, %1
store i64 -1, i64* %2
br label %133
15: ; preds = %9
br label %16
16: ; preds = %35, %15
%17 = load i64, i64* %4
%18 = mul i64 %17, 10
%19 = load i8*, i8** %3
%20 = load i8, i8* %19
%21 = sext i8 %20 to i64
%22 = add i64 %18, %21
%23 = sub i64 %22, 48
store i64 %23, i64* %4
br label %24
24: ; preds = %16
%25 = load i8*, i8** %3
%26 = getelementptr inbounds i8, i8* %25, i32 1
store i8* %26, i8** %3
%27 = load i8, i8* %26
%28 = sext i8 %27 to i32
%29 = icmp sge i32 %28, 48
br i1 %29, label %30, label %35
30: ; preds = %24
%31 = load i8*, i8** %3
%32 = load i8, i8* %31
%33 = sext i8 %32 to i32
%34 = icmp sle i32 %33, 57
br label %35
35: ; preds = %30, %24
%36 = phi i1 [ false, %24 ], [ %34, %30 ]
br i1 %36, label %16, label %37
37: ; preds = %35
%38 = load i8*, i8** %3
%39 = load i8, i8* %38
%40 = icmp ne i8 %39, 0
br i1 %40, label %44, label %41
41: ; preds = %37
%42 = load i64, i64* %4
%43 = mul i64 %42, 1000
store i64 %43, i64* %2
br label %133
44: ; preds = %37
%45 = load i8*, i8** %3
%46 = load i8, i8* %45
%47 = sext i8 %46 to i32
%48 = icmp ne i32 %47, 46
br i1 %48, label %49, label %50
49: ; preds = %44
store i64 -1, i64* %2
br label %133
50: ; preds = %44
%51 = load i8*, i8** %3
%52 = getelementptr inbounds i8, i8* %51, i32 1
store i8* %52, i8** %3
%53 = load i8*, i8** %3
%54 = load i8, i8* %53
%55 = sext i8 %54 to i32
%56 = icmp slt i32 %55, 48
br i1 %56, label %62, label %57
57: ; preds = %50
%58 = load i8*, i8** %3
%59 = load i8, i8* %58
%60 = sext i8 %59 to i32
%61 = icmp sgt i32 %60, 57
br i1 %61, label %62, label %63
62: ; preds = %57, %50
store i64 -1, i64* %2
br label %133
63: ; preds = %57
%64 = load i64, i64* %4
%65 = mul i64 %64, 10
%66 = load i8*, i8** %3
%67 = load i8, i8* %66
%68 = sext i8 %67 to i64
%69 = add i64 %65, %68
%70 = sub i64 %69, 48
store i64 %70, i64* %4
%71 = load i8*, i8** %3
%72 = getelementptr inbounds i8, i8* %71, i32 1
store i8* %72, i8** %3
%73 = load i8*, i8** %3
%74 = load i8, i8* %73
%75 = icmp ne i8 %74, 0
br i1 %75, label %79, label %76
76: ; preds = %63
%77 = load i64, i64* %4
%78 = mul i64 %77, 100
store i64 %78, i64* %2
br label %133
79: ; preds = %63
%80 = load i8*, i8** %3
%81 = load i8, i8* %80
%82 = sext i8 %81 to i32
%83 = icmp slt i32 %82, 48
br i1 %83, label %89, label %84
84: ; preds = %79
%85 = load i8*, i8** %3
%86 = load i8, i8* %85
%87 = sext i8 %86 to i32
%88 = icmp sgt i32 %87, 57
br i1 %88, label %89, label %90
89: ; preds = %84, %79
store i64 -1, i64* %2
br label %133
90: ; preds = %84
%91 = load i64, i64* %4
%92 = mul i64 %91, 10
%93 = load i8*, i8** %3
%94 = load i8, i8* %93
%95 = sext i8 %94 to i64
%96 = add i64 %92, %95
%97 = sub i64 %96, 48
store i64 %97, i64* %4
%98 = load i8*, i8** %3
%99 = getelementptr inbounds i8, i8* %98, i32 1
store i8* %99, i8** %3
%100 = load i8*, i8** %3
%101 = load i8, i8* %100
%102 = icmp ne i8 %101, 0
br i1 %102, label %106, label %103
103: ; preds = %90
%104 = load i64, i64* %4
%105 = mul i64 %104, 10
store i64 %105, i64* %2
br label %133
106: ; preds = %90
%107 = load i8*, i8** %3
%108 = load i8, i8* %107
%109 = sext i8 %108 to i32
%110 = icmp slt i32 %109, 48
br i1 %110, label %116, label %111
111: ; preds = %106
%112 = load i8*, i8** %3
%113 = load i8, i8* %112
%114 = sext i8 %113 to i32
%115 = icmp sgt i32 %114, 57
br i1 %115, label %116, label %117
116: ; preds = %111, %106
store i64 -1, i64* %2
br label %133
117: ; preds = %111
%118 = load i64, i64* %4
%119 = mul i64 %118, 10
%120 = load i8*, i8** %3
%121 = load i8, i8* %120
%122 = sext i8 %121 to i64
%123 = add i64 %119, %122
%124 = sub i64 %123, 48
store i64 %124, i64* %4
%125 = load i8*, i8** %3
%126 = getelementptr inbounds i8, i8* %125, i32 1
store i8* %126, i8** %3
%127 = load i8*, i8** %3
%128 = load i8, i8* %127
%129 = icmp ne i8 %128, 0
br i1 %129, label %132, label %130
130: ; preds = %117
%131 = load i64, i64* %4
store i64 %131, i64* %2
br label %133
132: ; preds = %117
store i64 -1, i64* %2
br label %133
133: ; preds = %132, %130, %116, %103, %89, %76, %62, %49, %41, %14
%134 = load i64, i64* %2
ret i64 %134
}

LLVM IR (-O2):
define i64 @read_float_10E3(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = add i8 %2, -58
%4 = icmp ult i8 %3, -10
br i1 %4, label %60, label %5
5: ; preds = %1, %5
%6 = phi i8 [ %14, %5 ], [ %2, %1 ]
%7 = phi i8* [ %13, %5 ], [ %0, %1 ]
%8 = phi i64 [ %12, %5 ], [ 0, %1 ]
%9 = mul i64 %8, 10
%10 = zext i8 %6 to i64
%11 = add i64 %9, -48
%12 = add i64 %11, %10
%13 = getelementptr inbounds i8, i8* %7, i64 1
%14 = load i8, i8* %13
%15 = add i8 %14, -48
%16 = icmp ult i8 %15, 10
br i1 %16, label %5, label %17
17: ; preds = %5
switch i8 %14, label %60 [
i8 0, label %18
i8 46, label %20
]
18: ; preds = %17
%19 = mul i64 %12, 1000
br label %60
20: ; preds = %17
%21 = getelementptr inbounds i8, i8* %7, i64 2
%22 = load i8, i8* %21
%23 = add i8 %22, -58
%24 = icmp ult i8 %23, -10
br i1 %24, label %60, label %25
25: ; preds = %20
%26 = mul i64 %12, 10
%27 = zext i8 %22 to i64
%28 = add i64 %26, -48
%29 = add i64 %28, %27
%30 = getelementptr inbounds i8, i8* %7, i64 3
%31 = load i8, i8* %30
%32 = icmp eq i8 %31, 0
br i1 %32, label %33, label %35
33: ; preds = %25
%34 = mul i64 %29, 100
br label %60
35: ; preds = %25
%36 = add i8 %31, -58
%37 = icmp ult i8 %36, -10
br i1 %37, label %60, label %38
38: ; preds = %35
%39 = mul i64 %29, 10
%40 = zext i8 %31 to i64
%41 = add i64 %39, -48
%42 = add i64 %41, %40
%43 = getelementptr inbounds i8, i8* %7, i64 4
%44 = load i8, i8* %43
%45 = icmp eq i8 %44, 0
br i1 %45, label %46, label %48
46: ; preds = %38
%47 = mul i64 %42, 10
br label %60
48: ; preds = %38
%49 = add i8 %44, -58
%50 = icmp ult i8 %49, -10
br i1 %50, label %60, label %51
51: ; preds = %48
%52 = getelementptr inbounds i8, i8* %7, i64 5
%53 = load i8, i8* %52
%54 = icmp eq i8 %53, 0
br i1 %54, label %55, label %60
55: ; preds = %51
%56 = mul i64 %42, 10
%57 = zext i8 %44 to i64
%58 = add i64 %56, -48
%59 = add i64 %58, %57
br label %60
60: ; preds = %51, %48, %35, %20, %17, %1, %55, %46, %33, %18
%61 = phi i64 [ %59, %55 ], [ %47, %46 ], [ %34, %33 ], [ %19, %18 ], [ -1, %1 ], [ -1, %17 ], [ -1, %20 ], [ -1, %35 ], [ -1, %48 ], [ -1, %51 ]
ret i64 %61
}