double theta_est(int k_obs, int n) {
  double kval(double theta, int n);
  double xlow, xhigh, xmid;
  double eps;
  eps = 0.00001;
  xlow = 0.1;
  while (kval(xlow, n) > k_obs)
    xlow /= 10.0;
  xhigh = 10.0;
  while (kval(xhigh, n) < k_obs)
    xhigh *= 10.0;
  while ((xhigh - xlow) > eps) {
    xmid = (xhigh + xlow) / 2.0;
    if (kval(xmid, n) > k_obs)
      xhigh = xmid;
    else
      xlow = xmid;
  }
  return xmid;
}


x86 assembly (clang, -O0):
<theta_est>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movsd  0xee2(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xecd(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%edi
call   1030 <kval@plt>
cvtsi2sdl -0x4(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jbe    116f <theta_est+0x5f>
movsd  -0x10(%rbp),%xmm0
movsd  0xeaf(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    1138 <theta_est+0x28>
movsd  0xe99(%rip),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
mov    -0x8(%rbp),%edi
call   1030 <kval@plt>
movaps %xmm0,%xmm1
cvtsi2sdl -0x4(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11b2 <theta_est+0xa2>
movsd  0xe6d(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    117c <theta_est+0x6c>
jmp    11b7 <theta_est+0xa7>
movsd  -0x18(%rbp),%xmm0
subsd  -0x10(%rbp),%xmm0
ucomisd -0x28(%rbp),%xmm0
jbe    1221 <theta_est+0x111>
movsd  -0x18(%rbp),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  0xe3a(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
mov    -0x8(%rbp),%edi
call   1030 <kval@plt>
cvtsi2sdl -0x4(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jbe    1212 <theta_est+0x102>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    121c <theta_est+0x10c>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    11b7 <theta_est+0xa7>
movsd  -0x20(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<theta_est>:
push   %rbp
push   %rbx
sub    $0x38,%rsp
mov    %esi,%ebx
mov    %edi,%ebp
movsd  0xede(%rip),%xmm0
mov    %esi,%edi
call   1030 <kval@plt>
cvtsi2sd %ebp,%xmm1
movsd  %xmm1,0x8(%rsp)
ucomisd %xmm1,%xmm0
movsd  0xec1(%rip),%xmm0
jbe    1176 <theta_est+0x66>
movsd  0xeb7(%rip),%xmm0
nopl   0x0(%rax)
divsd  0xeb0(%rip),%xmm0
movsd  %xmm0,(%rsp)
movsd  (%rsp),%xmm0
mov    %ebx,%edi
call   1030 <kval@plt>
ucomisd 0x8(%rsp),%xmm0
movsd  (%rsp),%xmm0
ja     1150 <theta_est+0x40>
movsd  %xmm0,(%rsp)
movsd  0xe85(%rip),%xmm0
mov    %ebx,%edi
call   1030 <kval@plt>
movsd  0xe76(%rip),%xmm3
movsd  0x8(%rsp),%xmm1
ucomisd %xmm0,%xmm1
jbe    11db <theta_est+0xcb>
movsd  0xe62(%rip),%xmm3
cs nopw 0x0(%rax,%rax,1)
mulsd  0xe50(%rip),%xmm3
movapd %xmm3,0x10(%rsp)
movapd %xmm3,%xmm0
mov    %ebx,%edi
call   1030 <kval@plt>
movapd 0x10(%rsp),%xmm3
movsd  0x8(%rsp),%xmm1
ucomisd %xmm0,%xmm1
ja     11b0 <theta_est+0xa0>
movapd %xmm3,%xmm0
movsd  (%rsp),%xmm2
subsd  %xmm2,%xmm0
ucomisd 0xe20(%rip),%xmm0
ja     1229 <theta_est+0x119>
movapd %xmm4,%xmm0
add    $0x38,%rsp
pop    %rbx
pop    %rbp
ret
nopl   (%rax)
cmpltsd %xmm0,%xmm1
movapd %xmm1,%xmm0
andpd  %xmm4,%xmm0
andnpd 0x10(%rsp),%xmm1
orpd   %xmm0,%xmm1
movapd %xmm1,%xmm3
subsd  %xmm2,%xmm1
ucomisd 0xde9(%rip),%xmm1
jbe    11f2 <theta_est+0xe2>
movapd %xmm3,0x10(%rsp)
movsd  %xmm2,(%rsp)
addsd  %xmm2,%xmm3
mulsd  0xdd8(%rip),%xmm3
movapd %xmm3,0x20(%rsp)
movapd %xmm3,%xmm0
mov    %ebx,%edi
call   1030 <kval@plt>
movapd 0x20(%rsp),%xmm4
movsd  0x8(%rsp),%xmm1
movsd  (%rsp),%xmm2
ucomisd %xmm1,%xmm0
ja     1200 <theta_est+0xf0>
movapd %xmm4,%xmm2
jmp    1200 <theta_est+0xf0>

LLVM IR (-O0):
define double @theta_est(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
store i32 %0, i32* %3
store i32 %1, i32* %4
store double 1.000000e-05, double* %8
store double 1.000000e-01, double* %5
br label %9
9: ; preds = %16, %2
%10 = load double, double* %5
%11 = load i32, i32* %4
%12 = call double @kval(double %10, i32 %11)
%13 = load i32, i32* %3
%14 = sitofp i32 %13 to double
%15 = fcmp ogt double %12, %14
br i1 %15, label %16, label %19
16: ; preds = %9
%17 = load double, double* %5
%18 = fdiv double %17, 1.000000e+01
store double %18, double* %5
br label %9
19: ; preds = %9
store double 1.000000e+01, double* %6
br label %20
20: ; preds = %27, %19
%21 = load double, double* %6
%22 = load i32, i32* %4
%23 = call double @kval(double %21, i32 %22)
%24 = load i32, i32* %3
%25 = sitofp i32 %24 to double
%26 = fcmp olt double %23, %25
br i1 %26, label %27, label %30
27: ; preds = %20
%28 = load double, double* %6
%29 = fmul double %28, 1.000000e+01
store double %29, double* %6
br label %20
30: ; preds = %20
br label %31
31: ; preds = %52, %30
%32 = load double, double* %6
%33 = load double, double* %5
%34 = fsub double %32, %33
%35 = load double, double* %8
%36 = fcmp ogt double %34, %35
br i1 %36, label %37, label %53
37: ; preds = %31
%38 = load double, double* %6
%39 = load double, double* %5
%40 = fadd double %38, %39
%41 = fdiv double %40, 2.000000e+00
store double %41, double* %7
%42 = load double, double* %7
%43 = load i32, i32* %4
%44 = call double @kval(double %42, i32 %43)
%45 = load i32, i32* %3
%46 = sitofp i32 %45 to double
%47 = fcmp ogt double %44, %46
br i1 %47, label %48, label %50
48: ; preds = %37
%49 = load double, double* %7
store double %49, double* %6
br label %52
50: ; preds = %37
%51 = load double, double* %7
store double %51, double* %5
br label %52
52: ; preds = %50, %48
br label %31
53: ; preds = %31
%54 = load double, double* %7
ret double %54
}

LLVM IR (-O2):
define double @theta_est(i32 %0, i32 %1) {
%3 = tail call double @kval(double 1.000000e-01, i32 %1)
%4 = sitofp i32 %0 to double
%5 = fcmp ogt double %3, %4
br i1 %5, label %10, label %6
6: ; preds = %10, %2
%7 = phi double [ 1.000000e-01, %2 ], [ %12, %10 ]
%8 = tail call double @kval(double 1.000000e+01, i32 %1)
%9 = fcmp olt double %8, %4
br i1 %9, label %19, label %15
10: ; preds = %2, %10
%11 = phi double [ %12, %10 ], [ 1.000000e-01, %2 ]
%12 = fdiv double %11, 1.000000e+01
%13 = tail call double @kval(double %12, i32 %1)
%14 = fcmp ogt double %13, %4
br i1 %14, label %10, label %6
15: ; preds = %19, %6
%16 = phi double [ 1.000000e+01, %6 ], [ %21, %19 ]
%17 = fsub double %16, %7
%18 = fcmp ogt double %17, 1.000000e-05
br i1 %18, label %24, label %35
19: ; preds = %6, %19
%20 = phi double [ %21, %19 ], [ 1.000000e+01, %6 ]
%21 = fmul double %20, 1.000000e+01
%22 = tail call double @kval(double %21, i32 %1)
%23 = fcmp olt double %22, %4
br i1 %23, label %19, label %15
24: ; preds = %15, %24
%25 = phi double [ %32, %24 ], [ %7, %15 ]
%26 = phi double [ %31, %24 ], [ %16, %15 ]
%27 = fadd double %26, %25
%28 = fmul double %27, 5.000000e-01
%29 = tail call double @kval(double %28, i32 %1)
%30 = fcmp ogt double %29, %4
%31 = select i1 %30, double %28, double %26
%32 = select i1 %30, double %25, double %28
%33 = fsub double %31, %32
%34 = fcmp ogt double %33, 1.000000e-05
br i1 %34, label %24, label %35
35: ; preds = %24, %15
%36 = phi double [ undef, %15 ], [ %28, %24 ]
ret double %36
}