#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 UINT_MAX;
unsigned long ULONG_MAX;
double ncr(double n, double r) {
  if (n < 0.0 || r < 0.0 || n < r)
    return (0.0 / 0.0);
  if (n > UINT_MAX || r > UINT_MAX)
    return (1.0 / 0.0);
  unsigned long int un = (unsigned int)(n), ur = (unsigned int)(r), i;
  unsigned long int result = 1;
  if (ur > un / 2)
    ur = un - ur;
  for (i = 1; i <= ur; i++) {
    if (result > ULONG_MAX / (un - ur + i))
      return (1.0 / 0.0);
    result *= un - ur + i;
    result /= i;
  }
  return result;
}


x86 assembly (clang, -O0):
<ncr>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
ja     113e <ncr+0x3e>
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
ja     113e <ncr+0x3e>
movsd  -0x10(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1150 <ncr+0x50>
movsd  0xee2(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    128d <ncr+0x18d>
movsd  -0x10(%rbp),%xmm0
mov    0x2e8c(%rip),%rax
ucomisd (%rax),%xmm0
ja     117c <ncr+0x7c>
movsd  -0x18(%rbp),%xmm0
mov    0x2e76(%rip),%rax
ucomisd (%rax),%xmm0
jbe    118e <ncr+0x8e>
movsd  0xe9c(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    128d <ncr+0x18d>
cvttsd2si -0x10(%rbp),%rax
mov    %eax,%eax
mov    %rax,-0x20(%rbp)
cvttsd2si -0x18(%rbp),%rax
mov    %eax,%eax
mov    %rax,-0x28(%rbp)
movq   $0x1,-0x38(%rbp)
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
shr    $0x1,%rcx
cmp    %rcx,%rax
jbe    11cf <ncr+0xcf>
mov    -0x20(%rbp),%rax
sub    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
movq   $0x1,-0x30(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x28(%rbp),%rax
ja     1261 <ncr+0x161>
mov    -0x38(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    0x2ddc(%rip),%rax
mov    (%rax),%rax
mov    -0x20(%rbp),%rcx
sub    -0x28(%rbp),%rcx
add    -0x30(%rbp),%rcx
xor    %edx,%edx
div    %rcx
mov    %rax,%rcx
mov    -0x40(%rbp),%rax
cmp    %rcx,%rax
jbe    122a <ncr+0x12a>
movsd  0xe00(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    128d <ncr+0x18d>
mov    -0x20(%rbp),%rax
sub    -0x28(%rbp),%rax
add    -0x30(%rbp),%rax
imul   -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rcx
mov    -0x38(%rbp),%rax
xor    %edx,%edx
div    %rcx
mov    %rax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    11d7 <ncr+0xd7>
movaps 0xd98(%rip),%xmm1
movq   -0x38(%rbp),%xmm0
punpckldq %xmm1,%xmm0
movapd 0xd97(%rip),%xmm1
subpd  %xmm1,%xmm0
movaps %xmm0,%xmm1
unpckhpd %xmm0,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<ncr>:
movapd %xmm0,%xmm2
ucomisd %xmm0,%xmm1
movsd  0xef0(%rip),%xmm0
ja     1230 <ncr+0x130>
xorpd  %xmm3,%xmm3
ucomisd %xmm2,%xmm3
ja     1230 <ncr+0x130>
ucomisd %xmm1,%xmm3
ja     1230 <ncr+0x130>
mov    0x2eb3(%rip),%rax
movsd  (%rax),%xmm3
ucomisd %xmm3,%xmm2
movsd  0xec3(%rip),%xmm0
ja     1230 <ncr+0x130>
ucomisd %xmm3,%xmm1
ja     1230 <ncr+0x130>
cvttsd2si %xmm2,%rax
cvttsd2si %xmm1,%rcx
mov    %eax,%r8d
mov    %ecx,%eax
mov    %r8,%rcx
shr    %rcx
mov    %r8,%r9
sub    %rax,%r9
cmp    %rax,%rcx
cmovae %rax,%r9
test   %r9,%r9
je     1206 <ncr+0x106>
mov    0x2e49(%rip),%rax
mov    (%rax),%r10
sub    %r9,%r8
mov    $0x1,%esi
mov    $0x1,%edi
jmp    11b4 <ncr+0xb4>
nopl   0x0(%rax)
mov    %rsi,%rax
xor    %edx,%edx
div    %rdi
mov    %rax,%rsi
add    $0x1,%rdi
cmp    %r9,%rdi
ja     120f <ncr+0x10f>
lea    (%r8,%rdi,1),%rcx
mov    %r10,%rax
or     %rcx,%rax
shr    $0x20,%rax
je     11e0 <ncr+0xe0>
mov    %r10,%rax
xor    %edx,%edx
div    %rcx
cmp    %rax,%rsi
jbe    11ec <ncr+0xec>
jmp    1230 <ncr+0x130>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %r10d,%eax
xor    %edx,%edx
div    %ecx
cmp    %rax,%rsi
ja     1230 <ncr+0x130>
imul   %rcx,%rsi
mov    %rsi,%rax
or     %rdi,%rax
shr    $0x20,%rax
jne    11a0 <ncr+0xa0>
mov    %esi,%eax
xor    %edx,%edx
div    %edi
mov    %eax,%esi
jmp    11ab <ncr+0xab>
movsd  0xe02(%rip),%xmm0
ret
movq   %rsi,%xmm1
punpckldq 0xe04(%rip),%xmm1
subpd  0xe0c(%rip),%xmm1
movapd %xmm1,%xmm0
unpckhpd %xmm1,%xmm0
addsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
@UINT_MAX = global double 0.000000e+00
@ULONG_MAX = global i64 0
define double @ncr(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
store double %0, double* %4
store double %1, double* %5
%10 = load double, double* %4
%11 = fcmp olt double %10, 0.000000e+00
br i1 %11, label %19, label %12
12: ; preds = %2
%13 = load double, double* %5
%14 = fcmp olt double %13, 0.000000e+00
br i1 %14, label %19, label %15
15: ; preds = %12
%16 = load double, double* %4
%17 = load double, double* %5
%18 = fcmp olt double %16, %17
br i1 %18, label %19, label %20
19: ; preds = %15, %12, %2
store double 0x7FF8000000000000, double* %3
br label %77
20: ; preds = %15
%21 = load double, double* %4
%22 = load double, double* @UINT_MAX
%23 = fcmp ogt double %21, %22
br i1 %23, label %28, label %24
24: ; preds = %20
%25 = load double, double* %5
%26 = load double, double* @UINT_MAX
%27 = fcmp ogt double %25, %26
br i1 %27, label %28, label %29
28: ; preds = %24, %20
store double 0x7FF0000000000000, double* %3
br label %77
29: ; preds = %24
%30 = load double, double* %4
%31 = fptoui double %30 to i32
%32 = zext i32 %31 to i64
store i64 %32, i64* %6
%33 = load double, double* %5
%34 = fptoui double %33 to i32
%35 = zext i32 %34 to i64
store i64 %35, i64* %7
store i64 1, i64* %9
%36 = load i64, i64* %7
%37 = load i64, i64* %6
%38 = udiv i64 %37, 2
%39 = icmp ugt i64 %36, %38
br i1 %39, label %40, label %44
40: ; preds = %29
%41 = load i64, i64* %6
%42 = load i64, i64* %7
%43 = sub i64 %41, %42
store i64 %43, i64* %7
br label %44
44: ; preds = %40, %29
store i64 1, i64* %8
br label %45
45: ; preds = %71, %44
%46 = load i64, i64* %8
%47 = load i64, i64* %7
%48 = icmp ule i64 %46, %47
br i1 %48, label %49, label %74
49: ; preds = %45
%50 = load i64, i64* %9
%51 = load i64, i64* @ULONG_MAX
%52 = load i64, i64* %6
%53 = load i64, i64* %7
%54 = sub i64 %52, %53
%55 = load i64, i64* %8
%56 = add i64 %54, %55
%57 = udiv i64 %51, %56
%58 = icmp ugt i64 %50, %57
br i1 %58, label %59, label %60
59: ; preds = %49
store double 0x7FF0000000000000, double* %3
br label %77
60: ; preds = %49
%61 = load i64, i64* %6
%62 = load i64, i64* %7
%63 = sub i64 %61, %62
%64 = load i64, i64* %8
%65 = add i64 %63, %64
%66 = load i64, i64* %9
%67 = mul i64 %66, %65
store i64 %67, i64* %9
%68 = load i64, i64* %8
%69 = load i64, i64* %9
%70 = udiv i64 %69, %68
store i64 %70, i64* %9
br label %71
71: ; preds = %60
%72 = load i64, i64* %8
%73 = add i64 %72, 1
store i64 %73, i64* %8
br label %45
74: ; preds = %45
%75 = load i64, i64* %9
%76 = uitofp i64 %75 to double
store double %76, double* %3
br label %77
77: ; preds = %74, %59, %28, %19
%78 = load double, double* %3
ret double %78
}

LLVM IR (-O2):
@UINT_MAX = global double 0.000000e+00
@ULONG_MAX = global i64 0
define double @ncr(double %0, double %1) {
%3 = fcmp olt double %0, 0.000000e+00
%4 = fcmp olt double %1, 0.000000e+00
%5 = or i1 %3, %4
%6 = fcmp olt double %0, %1
%7 = or i1 %6, %5
br i1 %7, label %39, label %8
8: ; preds = %2
%9 = load double, double* @UINT_MAX
%10 = fcmp olt double %9, %0
%11 = fcmp olt double %9, %1
%12 = or i1 %10, %11
br i1 %12, label %39, label %13
13: ; preds = %8
%14 = fptoui double %0 to i32
%15 = zext i32 %14 to i64
%16 = fptoui double %1 to i32
%17 = zext i32 %16 to i64
%18 = lshr i64 %15, 1
%19 = icmp ult i64 %18, %17
%20 = sub nsw i64 %15, %17
%21 = select i1 %19, i64 %20, i64 %17
%22 = icmp eq i64 %21, 0
br i1 %22, label %39, label %23
23: ; preds = %13
%24 = load i64, i64* @ULONG_MAX
%25 = sub nsw i64 %15, %21
br label %26
26: ; preds = %23, %32
%27 = phi i64 [ 1, %23 ], [ %34, %32 ]
%28 = phi i64 [ 1, %23 ], [ %35, %32 ]
%29 = add i64 %28, %25
%30 = udiv i64 %24, %29
%31 = icmp ugt i64 %27, %30
br i1 %31, label %39, label %32
32: ; preds = %26
%33 = mul i64 %27, %29
%34 = udiv i64 %33, %28
%35 = add i64 %28, 1
%36 = icmp ugt i64 %35, %21
br i1 %36, label %37, label %26
37: ; preds = %32
%38 = uitofp i64 %34 to double
br label %39
39: ; preds = %26, %13, %37, %8, %2
%40 = phi double [ 0x7FF8000000000000, %2 ], [ 0x7FF0000000000000, %8 ], [ 1.000000e+00, %13 ], [ %38, %37 ], [ 0x7FF0000000000000, %26 ]
ret double %40
}