#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 */
int /*<<< orphan*/ error2(char *);
scalar_t__ log(double);
double Binomial(double n, double k, double *scale) {
  double c, i, large = 1e99;
  *scale = 0;
  if (k == 0)
    return (1);
  if (k < 0 || (int)k != k)
    error2("k is not a whole number in Binomial.");
  if (n > 0 && (int)n == n)
    k = ((k) < (n - k) ? (k) : (n - k));
  for (i = 1, c = 1; i <= k; i++) {
    c *= (n - k + i) / i;
    if (c > large) {
      *scale += log(c);
      c = 1;
    }
  }
  return (c);
}


x86 assembly (clang, -O0):
<Binomial>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %rdi,-0x20(%rbp)
movsd  0xec2(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x20(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1178 <Binomial+0x58>
jp     1178 <Binomial+0x58>
movsd  0xe9a(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12c8 <Binomial+0x1a8>
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
ja     11a5 <Binomial+0x85>
cvttsd2si -0x18(%rbp),%eax
cvtsi2sd %eax,%xmm0
ucomisd -0x18(%rbp),%xmm0
jne    11a5 <Binomial+0x85>
jp     11a5 <Binomial+0x85>
jmp    11b1 <Binomial+0x91>
lea    0xe64(%rip),%rdi
call   1030 <error2@plt>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    121e <Binomial+0xfe>
cvttsd2si -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm0
ucomisd -0x10(%rbp),%xmm0
jne    121e <Binomial+0xfe>
jp     121e <Binomial+0xfe>
movsd  -0x18(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1205 <Binomial+0xe5>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    1214 <Binomial+0xf4>
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xde2(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  0xdd5(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x30(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jb     12be <Binomial+0x19e>
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
addsd  -0x30(%rbp),%xmm0
divsd  -0x30(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    12a2 <Binomial+0x182>
movsd  -0x28(%rbp),%xmm0
call   1040 <log@plt>
cvtsi2sd %rax,%xmm0
mov    -0x20(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
movsd  0xd6b(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    12a7 <Binomial+0x187>
movsd  0xd59(%rip),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    1238 <Binomial+0x118>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Binomial>:
push   %rbx
sub    $0x30,%rsp
movapd %xmm0,%xmm3
movq   $0x0,(%rdi)
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jne    1146 <Binomial+0x26>
jp     1146 <Binomial+0x26>
movsd  0xebc(%rip),%xmm0
jmp    11b5 <Binomial+0x95>
mov    %rdi,%rbx
ucomisd %xmm1,%xmm0
ja     115f <Binomial+0x3f>
cvttpd2dq %xmm1,%xmm0
cvtdq2pd %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jne    115f <Binomial+0x3f>
jnp    1181 <Binomial+0x61>
lea    0xeaa(%rip),%rdi
movapd %xmm1,0x10(%rsp)
movapd %xmm3,(%rsp)
call   1030 <error2@plt>
movapd (%rsp),%xmm3
movapd 0x10(%rsp),%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm3
jbe    11a7 <Binomial+0x87>
cvttpd2dq %xmm3,%xmm0
cvtdq2pd %xmm0,%xmm0
ucomisd %xmm3,%xmm0
jne    11a7 <Binomial+0x87>
jp     11a7 <Binomial+0x87>
movapd %xmm3,%xmm0
subsd  %xmm1,%xmm0
minsd  %xmm0,%xmm1
movsd  0xe51(%rip),%xmm0
ucomisd %xmm0,%xmm1
jae    11bb <Binomial+0x9b>
add    $0x30,%rsp
pop    %rbx
ret
subsd  %xmm1,%xmm3
movsd  0xe39(%rip),%xmm4
movsd  0xe39(%rip),%xmm5
movapd %xmm4,%xmm6
movapd %xmm4,%xmm2
movapd %xmm1,0x10(%rsp)
movapd %xmm3,(%rsp)
jmp    11fe <Binomial+0xde>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
addsd  %xmm4,%xmm6
ucomisd %xmm6,%xmm1
movapd %xmm0,%xmm2
jb     11b5 <Binomial+0x95>
movapd %xmm3,%xmm0
addsd  %xmm6,%xmm0
divsd  %xmm6,%xmm0
mulsd  %xmm2,%xmm0
ucomisd %xmm5,%xmm0
jbe    11f0 <Binomial+0xd0>
movsd  %xmm6,0x28(%rsp)
call   1040 <log@plt>
movsd  0x28(%rsp),%xmm6
movsd  0xddb(%rip),%xmm5
movsd  0xdcb(%rip),%xmm4
movapd (%rsp),%xmm3
movapd 0x10(%rsp),%xmm1
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  (%rbx),%xmm0
movsd  %xmm0,(%rbx)
movapd %xmm4,%xmm0
jmp    11f0 <Binomial+0xd0>

LLVM IR (-O0):
@.str = [37 x i8] c"k is not a whole number in Binomial.\00"
define double @Binomial(double %0, double %1, double* %2) {
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double*
%8 = alloca double
%9 = alloca double
%10 = alloca double
store double %0, double* %5
store double %1, double* %6
store double* %2, double** %7
store double 0x547D42AEA2879F2E, double* %10
%11 = load double*, double** %7
store double 0.000000e+00, double* %11
%12 = load double, double* %6
%13 = fcmp oeq double %12, 0.000000e+00
br i1 %13, label %14, label %15
14: ; preds = %3
store double 1.000000e+00, double* %4
br label %80
15: ; preds = %3
%16 = load double, double* %6
%17 = fcmp olt double %16, 0.000000e+00
br i1 %17, label %24, label %18
18: ; preds = %15
%19 = load double, double* %6
%20 = fptosi double %19 to i32
%21 = sitofp i32 %20 to double
%22 = load double, double* %6
%23 = fcmp une double %21, %22
br i1 %23, label %24, label %26
24: ; preds = %18, %15
%25 = call i32 @error2(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str, i64 0, i64 0))
br label %26
26: ; preds = %24, %18
%27 = load double, double* %5
%28 = fcmp ogt double %27, 0.000000e+00
br i1 %28, label %29, label %49
29: ; preds = %26
%30 = load double, double* %5
%31 = fptosi double %30 to i32
%32 = sitofp i32 %31 to double
%33 = load double, double* %5
%34 = fcmp oeq double %32, %33
br i1 %34, label %35, label %49
35: ; preds = %29
%36 = load double, double* %6
%37 = load double, double* %5
%38 = load double, double* %6
%39 = fsub double %37, %38
%40 = fcmp olt double %36, %39
br i1 %40, label %41, label %43
41: ; preds = %35
%42 = load double, double* %6
br label %47
43: ; preds = %35
%44 = load double, double* %5
%45 = load double, double* %6
%46 = fsub double %44, %45
br label %47
47: ; preds = %43, %41
%48 = phi double [ %42, %41 ], [ %46, %43 ]
store double %48, double* %6
br label %49
49: ; preds = %47, %29, %26
store double 1.000000e+00, double* %9
store double 1.000000e+00, double* %8
br label %50
50: ; preds = %75, %49
%51 = load double, double* %9
%52 = load double, double* %6
%53 = fcmp ole double %51, %52
br i1 %53, label %54, label %78
54: ; preds = %50
%55 = load double, double* %5
%56 = load double, double* %6
%57 = fsub double %55, %56
%58 = load double, double* %9
%59 = fadd double %57, %58
%60 = load double, double* %9
%61 = fdiv double %59, %60
%62 = load double, double* %8
%63 = fmul double %62, %61
store double %63, double* %8
%64 = load double, double* %8
%65 = load double, double* %10
%66 = fcmp ogt double %64, %65
br i1 %66, label %67, label %74
67: ; preds = %54
%68 = load double, double* %8
%69 = call i64 @log(double %68)
%70 = sitofp i64 %69 to double
%71 = load double*, double** %7
%72 = load double, double* %71
%73 = fadd double %72, %70
store double %73, double* %71
store double 1.000000e+00, double* %8
br label %74
74: ; preds = %67, %54
br label %75
75: ; preds = %74
%76 = load double, double* %9
%77 = fadd double %76, 1.000000e+00
store double %77, double* %9
br label %50
78: ; preds = %50
%79 = load double, double* %8
store double %79, double* %4
br label %80
80: ; preds = %78, %14
%81 = load double, double* %4
ret double %81
}

LLVM IR (-O2):
@.str = [37 x i8] c"k is not a whole number in Binomial.\00"
define double @Binomial(double %0, double %1, double* nocapture %2) {
store double 0.000000e+00, double* %2
%4 = fcmp oeq double %1, 0.000000e+00
br i1 %4, label %44, label %5
5: ; preds = %3
%6 = fcmp olt double %1, 0.000000e+00
br i1 %6, label %11, label %7
7: ; preds = %5
%8 = fptosi double %1 to i32
%9 = sitofp i32 %8 to double
%10 = fcmp une double %9, %1
br i1 %10, label %11, label %13
11: ; preds = %7, %5
%12 = tail call i32 @error2(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str, i64 0, i64 0))
br label %13
13: ; preds = %11, %7
%14 = fcmp ogt double %0, 0.000000e+00
br i1 %14, label %15, label %23
15: ; preds = %13
%16 = fptosi double %0 to i32
%17 = sitofp i32 %16 to double
%18 = fcmp oeq double %17, %0
br i1 %18, label %19, label %23
19: ; preds = %15
%20 = fsub double %0, %1
%21 = fcmp ogt double %20, %1
%22 = select i1 %21, double %1, double %20
br label %23
23: ; preds = %19, %15, %13
%24 = phi double [ %22, %19 ], [ %1, %15 ], [ %1, %13 ]
%25 = fcmp ult double %24, 1.000000e+00
br i1 %25, label %44, label %26
26: ; preds = %23
%27 = fsub double %0, %24
br label %28
28: ; preds = %26, %40
%29 = phi double [ 1.000000e+00, %26 ], [ %42, %40 ]
%30 = phi double [ 1.000000e+00, %26 ], [ %41, %40 ]
%31 = fadd double %27, %29
%32 = fdiv double %31, %29
%33 = fmul double %30, %32
%34 = fcmp ogt double %33, 0x547D42AEA2879F2E
br i1 %34, label %35, label %40
35: ; preds = %28
%36 = tail call i64 @log(double %33)
%37 = sitofp i64 %36 to double
%38 = load double, double* %2
%39 = fadd double %38, %37
store double %39, double* %2
br label %40
40: ; preds = %28, %35
%41 = phi double [ 1.000000e+00, %35 ], [ %33, %28 ]
%42 = fadd double %29, 1.000000e+00
%43 = fcmp ugt double %42, %24
br i1 %43, label %44, label %28
44: ; preds = %40, %23, %3
%45 = phi double [ 1.000000e+00, %3 ], [ 1.000000e+00, %23 ], [ %41, %40 ]
ret double %45
}