long double prob(int last, int total) {
  long double sum = 0.;
  long double tmp = 1.;
  int i;
  int j = total;
  if (2 * last == total)
    return 1.;
  if (2 * last > total)
    last = total - last;
  for (i = 0; i <= last; i++) {
    sum += tmp;
    tmp = tmp * (total - i) / (1 + i);
    while (j > 0 && tmp > 1)
      j--, sum *= 0.5, tmp *= 0.5;
  }
  while (j > 0)
    j--, sum *= 0.5;
  return 2. * sum;
}


x86 assembly (clang, -O0):
<prob>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x14(%rbp)
mov    %esi,-0x18(%rbp)
fldz
fstpt  -0x30(%rbp)
fld1
fstpt  -0x40(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,-0x48(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x1,%eax
cmp    -0x18(%rbp),%eax
jne    1133 <prob+0x33>
fld1
fstpt  -0x10(%rbp)
jmp    1226 <prob+0x126>
mov    -0x14(%rbp),%eax
shl    $0x1,%eax
cmp    -0x18(%rbp),%eax
jle    114b <prob+0x4b>
mov    -0x18(%rbp),%eax
sub    -0x14(%rbp),%eax
mov    %eax,-0x14(%rbp)
movl   $0x0,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     11f3 <prob+0xf3>
fldt   -0x40(%rbp)
fldt   -0x30(%rbp)
faddp  %st,%st(1)
fstpt  -0x30(%rbp)
fldt   -0x40(%rbp)
mov    -0x18(%rbp),%ecx
mov    -0x44(%rbp),%eax
sub    %eax,%ecx
mov    %ecx,-0x4c(%rbp)
fildl  -0x4c(%rbp)
fmulp  %st,%st(1)
add    $0x1,%eax
mov    %eax,-0x50(%rbp)
fildl  -0x50(%rbp)
fdivrp %st,%st(1)
fstpt  -0x40(%rbp)
xor    %eax,%eax
cmpl   $0x0,-0x48(%rbp)
mov    %al,-0x51(%rbp)
jle    11aa <prob+0xaa>
fldt   -0x40(%rbp)
fld1
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
seta   %al
mov    %al,-0x51(%rbp)
mov    -0x51(%rbp),%al
test   $0x1,%al
jne    11ba <prob+0xba>
jmp    11e0 <prob+0xe0>
mov    -0x48(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x48(%rbp)
fldt   -0x30(%rbp)
flds   0xe34(%rip)
fmul   %st,%st(1)
fxch   %st(1)
fstpt  -0x30(%rbp)
fldt   -0x40(%rbp)
fmulp  %st,%st(1)
fstpt  -0x40(%rbp)
jmp    118a <prob+0x8a>
jmp    11e5 <prob+0xe5>
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    1152 <prob+0x52>
jmp    11f8 <prob+0xf8>
cmpl   $0x0,-0x48(%rbp)
jle    121e <prob+0x11e>
mov    -0x48(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x48(%rbp)
fldt   -0x30(%rbp)
flds   0xdec(%rip)
fmulp  %st,%st(1)
fstpt  -0x30(%rbp)
jmp    11f8 <prob+0xf8>
fldt   -0x30(%rbp)
fadd   %st,%st(0)
fstpt  -0x10(%rbp)
fldt   -0x10(%rbp)
pop    %rbp
ret

x86 assembly (clang, -O2):
<prob>:
lea    (%rdi,%rdi,1),%ecx
fld1
cmp    %esi,%ecx
je     1210 <prob+0x110>
fstp   %st(0)
mov    %esi,%eax
sub    %edi,%eax
cmp    %esi,%ecx
cmovle %edi,%eax
fldz
test   %eax,%eax
js     1188 <prob+0x88>
fstp   %st(0)
cmp    %ecx,%esi
cmovl  %esi,%ecx
sub    %edi,%ecx
add    $0x1,%ecx
fldz
fld1
xor    %edx,%edx
mov    %esi,%eax
fld1
flds   0xec6(%rip)
jmp    1148 <prob+0x48>
nopl   0x0(%rax)
cmp    %ecx,%edx
fxch   %st(2)
fxch   %st(3)
je     1190 <prob+0x90>
fxch   %st(3)
fadd   %st(2),%st
mov    %esi,%edi
sub    %edx,%edi
mov    %edi,-0x4(%rsp)
fxch   %st(2)
fimull -0x4(%rsp)
add    $0x1,%edx
mov    %edx,-0x8(%rsp)
fidivl -0x8(%rsp)
test   %eax,%eax
jle    1140 <prob+0x40>
nopl   0x0(%rax)
fucomi %st(1),%st
jbe    1140 <prob+0x40>
mov    %eax,%edi
lea    -0x1(%rdi),%eax
fxch   %st(2)
fmul   %st(3),%st
fxch   %st(2)
fmul   %st(3),%st
cmp    $0x2,%edi
jae    1170 <prob+0x70>
jmp    1140 <prob+0x40>
mov    %esi,%eax
fldz
fldz
fldz
fstp   %st(2)
fstp   %st(0)
fstp   %st(0)
test   %eax,%eax
jle    1200 <prob+0x100>
lea    -0x1(%rax),%ecx
mov    %eax,%edx
fldz
and    $0x7,%edx
je     11c1 <prob+0xc1>
fstp   %st(0)
xor    %esi,%esi
nopw   0x0(%rax,%rax,1)
fmuls  0xe4a(%rip)
add    $0x1,%esi
cmp    %esi,%edx
jne    11b0 <prob+0xb0>
sub    %esi,%eax
fld    %st(0)
cmp    $0x7,%ecx
fldz
jb     120a <prob+0x10a>
fstp   %st(1)
fstp   %st(0)
add    $0xffffffff,%eax
flds   0xe2b(%rip)
fldz
fxch   %st(2)
fxch   %st(1)
nopl   0x0(%rax,%rax,1)
fstp   %st(2)
fmul   %st(1),%st
fmul   %st(1),%st
fmul   %st(1),%st
fmul   %st(1),%st
fmul   %st(1),%st
fmul   %st(1),%st
fmul   %st(1),%st
fmul   %st(1),%st
add    $0xfffffff8,%eax
cmp    $0xfffffffe,%eax
fldz
fxch   %st(2)
jb     11e0 <prob+0xe0>
jmp    120a <prob+0x10a>
fldz
fldz
fxch   %st(1)
fxch   %st(2)
fxch   %st(1)
fstp   %st(2)
fstp   %st(1)
fadd   %st,%st(0)
ret

LLVM IR (-O0):
define x86_fp80 @prob(i32 %0, i32 %1) {
%3 = alloca x86_fp80
%4 = alloca i32
%5 = alloca i32
%6 = alloca x86_fp80
%7 = alloca x86_fp80
%8 = alloca i32
%9 = alloca i32
store i32 %0, i32* %4
store i32 %1, i32* %5
store x86_fp80 0xK00000000000000000000, x86_fp80* %6
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %7
%10 = load i32, i32* %5
store i32 %10, i32* %9
%11 = load i32, i32* %4
%12 = mul nsw i32 2, %11
%13 = load i32, i32* %5
%14 = icmp eq i32 %12, %13
br i1 %14, label %15, label %16
15: ; preds = %2
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %3
br label %75
16: ; preds = %2
%17 = load i32, i32* %4
%18 = mul nsw i32 2, %17
%19 = load i32, i32* %5
%20 = icmp sgt i32 %18, %19
br i1 %20, label %21, label %25
21: ; preds = %16
%22 = load i32, i32* %5
%23 = load i32, i32* %4
%24 = sub nsw i32 %22, %23
store i32 %24, i32* %4
br label %25
25: ; preds = %21, %16
store i32 0, i32* %8
br label %26
26: ; preds = %60, %25
%27 = load i32, i32* %8
%28 = load i32, i32* %4
%29 = icmp sle i32 %27, %28
br i1 %29, label %30, label %63
30: ; preds = %26
%31 = load x86_fp80, x86_fp80* %7
%32 = load x86_fp80, x86_fp80* %6
%33 = fadd x86_fp80 %32, %31
store x86_fp80 %33, x86_fp80* %6
%34 = load x86_fp80, x86_fp80* %7
%35 = load i32, i32* %5
%36 = load i32, i32* %8
%37 = sub nsw i32 %35, %36
%38 = sitofp i32 %37 to x86_fp80
%39 = fmul x86_fp80 %34, %38
%40 = load i32, i32* %8
%41 = add nsw i32 1, %40
%42 = sitofp i32 %41 to x86_fp80
%43 = fdiv x86_fp80 %39, %42
store x86_fp80 %43, x86_fp80* %7
br label %44
44: ; preds = %52, %30
%45 = load i32, i32* %9
%46 = icmp sgt i32 %45, 0
br i1 %46, label %47, label %50
47: ; preds = %44
%48 = load x86_fp80, x86_fp80* %7
%49 = fcmp ogt x86_fp80 %48, 0xK3FFF8000000000000000
br label %50
50: ; preds = %47, %44
%51 = phi i1 [ false, %44 ], [ %49, %47 ]
br i1 %51, label %52, label %59
52: ; preds = %50
%53 = load i32, i32* %9
%54 = add nsw i32 %53, -1
store i32 %54, i32* %9
%55 = load x86_fp80, x86_fp80* %6
%56 = fmul x86_fp80 %55, 0xK3FFE8000000000000000
store x86_fp80 %56, x86_fp80* %6
%57 = load x86_fp80, x86_fp80* %7
%58 = fmul x86_fp80 %57, 0xK3FFE8000000000000000
store x86_fp80 %58, x86_fp80* %7
br label %44
59: ; preds = %50
br label %60
60: ; preds = %59
%61 = load i32, i32* %8
%62 = add nsw i32 %61, 1
store i32 %62, i32* %8
br label %26
63: ; preds = %26
br label %64
64: ; preds = %67, %63
%65 = load i32, i32* %9
%66 = icmp sgt i32 %65, 0
br i1 %66, label %67, label %72
67: ; preds = %64
%68 = load i32, i32* %9
%69 = add nsw i32 %68, -1
store i32 %69, i32* %9
%70 = load x86_fp80, x86_fp80* %6
%71 = fmul x86_fp80 %70, 0xK3FFE8000000000000000
store x86_fp80 %71, x86_fp80* %6
br label %64
72: ; preds = %64
%73 = load x86_fp80, x86_fp80* %6
%74 = fmul x86_fp80 0xK40008000000000000000, %73
store x86_fp80 %74, x86_fp80* %3
br label %75
75: ; preds = %72, %15
%76 = load x86_fp80, x86_fp80* %3
ret x86_fp80 %76
}

LLVM IR (-O2):
define x86_fp80 @prob(i32 %0, i32 %1) {
%3 = shl i32 %0, 1
%4 = icmp eq i32 %3, %1
br i1 %4, label %82, label %5
5: ; preds = %2
%6 = icmp sgt i32 %3, %1
%7 = sub nsw i32 %1, %0
%8 = select i1 %6, i32 %7, i32 %0
%9 = icmp slt i32 %8, 0
br i1 %9, label %19, label %10
10: ; preds = %5
%11 = call i32 @llvm.smin.i32(i32 %1, i32 %3)
%12 = add i32 %11, 1
%13 = sub i32 %12, %0
br label %40
14: ; preds = %55, %40
%15 = phi x86_fp80 [ %45, %40 ], [ %60, %55 ]
%16 = phi x86_fp80 [ %51, %40 ], [ %61, %55 ]
%17 = phi i32 [ %41, %40 ], [ %59, %55 ]
%18 = icmp eq i32 %49, %13
br i1 %18, label %19, label %40
19: ; preds = %14, %5
%20 = phi x86_fp80 [ 0xK00000000000000000000, %5 ], [ %15, %14 ]
%21 = phi i32 [ %1, %5 ], [ %17, %14 ]
%22 = icmp sgt i32 %21, 0
br i1 %22, label %23, label %79
23: ; preds = %19
%24 = add i32 %21, -1
%25 = and i32 %21, 7
%26 = icmp eq i32 %25, 0
br i1 %26, label %35, label %27
27: ; preds = %23, %27
%28 = phi i32 [ %31, %27 ], [ %21, %23 ]
%29 = phi x86_fp80 [ %32, %27 ], [ %20, %23 ]
%30 = phi i32 [ %33, %27 ], [ 0, %23 ]
%31 = add nsw i32 %28, -1
%32 = fmul x86_fp80 %29, 0xK3FFE8000000000000000
%33 = add i32 %30, 1
%34 = icmp eq i32 %33, %25
br i1 %34, label %35, label %27
35: ; preds = %27, %23
%36 = phi i32 [ %21, %23 ], [ %31, %27 ]
%37 = phi x86_fp80 [ %20, %23 ], [ %32, %27 ]
%38 = phi x86_fp80 [ undef, %23 ], [ %32, %27 ]
%39 = icmp ult i32 %24, 7
br i1 %39, label %79, label %65
40: ; preds = %10, %14
%41 = phi i32 [ %17, %14 ], [ %1, %10 ]
%42 = phi i32 [ %49, %14 ], [ 0, %10 ]
%43 = phi x86_fp80 [ %16, %14 ], [ 0xK3FFF8000000000000000, %10 ]
%44 = phi x86_fp80 [ %15, %14 ], [ 0xK00000000000000000000, %10 ]
%45 = fadd x86_fp80 %44, %43
%46 = sub nsw i32 %1, %42
%47 = sitofp i32 %46 to x86_fp80
%48 = fmul x86_fp80 %43, %47
%49 = add nuw i32 %42, 1
%50 = sitofp i32 %49 to x86_fp80
%51 = fdiv x86_fp80 %48, %50
%52 = icmp sgt i32 %41, 0
%53 = fcmp ogt x86_fp80 %51, 0xK3FFF8000000000000000
%54 = select i1 %52, i1 %53, i1 false
br i1 %54, label %55, label %14
55: ; preds = %40, %55
%56 = phi i32 [ %59, %55 ], [ %41, %40 ]
%57 = phi x86_fp80 [ %61, %55 ], [ %51, %40 ]
%58 = phi x86_fp80 [ %60, %55 ], [ %45, %40 ]
%59 = add nsw i32 %56, -1
%60 = fmul x86_fp80 %58, 0xK3FFE8000000000000000
%61 = fmul x86_fp80 %57, 0xK3FFE8000000000000000
%62 = icmp ugt i32 %56, 1
%63 = fcmp ogt x86_fp80 %61, 0xK3FFF8000000000000000
%64 = select i1 %62, i1 %63, i1 false
br i1 %64, label %55, label %14
65: ; preds = %35, %65
%66 = phi i32 [ %75, %65 ], [ %36, %35 ]
%67 = phi x86_fp80 [ %76, %65 ], [ %37, %35 ]
%68 = fmul x86_fp80 %67, 0xK3FFE8000000000000000
%69 = fmul x86_fp80 %68, 0xK3FFE8000000000000000
%70 = fmul x86_fp80 %69, 0xK3FFE8000000000000000
%71 = fmul x86_fp80 %70, 0xK3FFE8000000000000000
%72 = fmul x86_fp80 %71, 0xK3FFE8000000000000000
%73 = fmul x86_fp80 %72, 0xK3FFE8000000000000000
%74 = fmul x86_fp80 %73, 0xK3FFE8000000000000000
%75 = add nsw i32 %66, -8
%76 = fmul x86_fp80 %74, 0xK3FFE8000000000000000
%77 = add i32 %66, -9
%78 = icmp ult i32 %77, -2
br i1 %78, label %65, label %79
79: ; preds = %35, %65, %19
%80 = phi x86_fp80 [ %20, %19 ], [ %38, %35 ], [ %76, %65 ]
%81 = fmul x86_fp80 %80, 0xK40008000000000000000
br label %82
82: ; preds = %2, %79
%83 = phi x86_fp80 [ %81, %79 ], [ 0xK3FFF8000000000000000, %2 ]
ret x86_fp80 %83
}