#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 _sqr(double);
double _stirling_correction(long k) {
  static const double C1 = 8.33333333333333333e-02;
  static const double C3 = -2.77777777777777778e-03;
  static const double C5 = 7.93650793650793651e-04;
  static const double C7 = -5.95238095238095238e-04;
  static const double c[31] = {
      0.0,
      8.106146679532726e-02,
      4.134069595540929e-02,
      2.767792568499834e-02,
      2.079067210376509e-02,
      1.664469118982119e-02,
      1.387612882307075e-02,
      1.189670994589177e-02,
      1.041126526197209e-02,
      9.255462182712733e-03,
      8.330563433362871e-03,
      7.573675487951841e-03,
      6.942840107209530e-03,
      6.408994188004207e-03,
      5.951370112758848e-03,
      5.554733551962801e-03,
      5.207655919609640e-03,
      4.901395948434738e-03,
      4.629153749334029e-03,
      4.385560249232324e-03,
      4.166319691996922e-03,
      3.967954218640860e-03,
      3.787618068444430e-03,
      3.622960224683090e-03,
      3.472021382978770e-03,
      3.333155636728090e-03,
      3.204970228055040e-03,
      3.086278682608780e-03,
      2.976063983550410e-03,
      2.873449362352470e-03,
      2.777674929752690e-03,
  };
  double r, rr;
  if (k > 30) {
    r = 1.0 / (double)k;
    rr = _sqr(r);
    return (r * (C1 + rr * (C3 + rr * (C5 + rr * C7))));
  } else {
    return c[k];
  }
}


x86 assembly (clang, -O0):
<_stirling_correction>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
cmpq   $0x1e,-0x10(%rbp)
jle    11a7 <_stirling_correction+0x97>
cvtsi2sdq -0x10(%rbp),%xmm1
movsd  0xeeb(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
call   1030 <_sqr@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
movsd  -0x20(%rbp),%xmm3
movsd  0xea7(%rip),%xmm4
mulsd  %xmm4,%xmm3
movsd  0xea3(%rip),%xmm4
addsd  %xmm4,%xmm3
mulsd  %xmm3,%xmm2
movsd  0xe83(%rip),%xmm3
addsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm1
movsd  0xe6b(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11bc <_stirling_correction+0xac>
mov    -0x10(%rbp),%rcx
lea    0xe9e(%rip),%rax
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<_stirling_correction>:
push   %rax
cmp    $0x1f,%rdi
jl     1169 <_stirling_correction+0x59>
cvtsi2sd %rdi,%xmm1
movsd  0xedc(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,(%rsp)
call   1030 <_sqr@plt>
movapd %xmm0,%xmm1
movsd  0xeca(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xec6(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xec2(%rip),%xmm0
mulsd  %xmm1,%xmm0
addsd  0xebe(%rip),%xmm0
mulsd  (%rsp),%xmm0
pop    %rax
ret
lea    0xec0(%rip),%rax
movsd  (%rax,%rdi,8),%xmm0
pop    %rax
ret

LLVM IR (-O0):
@_stirling_correction.C1 = internal constant double 0x3FB5555555555555
@_stirling_correction.C3 = internal constant double 0xBF66C16C16C16C17
@_stirling_correction.C5 = internal constant double 0x3F4A01A01A01A01A
@_stirling_correction.C7 = internal constant double 0xBF43813813813814
@_stirling_correction.c = internal constant [31 x double] [double 0.000000e+00, double 0x3FB4C071BCDA0A5B, double 0x3FA52A9B923EA648, double 0x3F9C579A268D80B3, double 0x3F954A2662FD78A8, double 0x3F910B4E513FCBEC, double 0x3F8C6B167BEBDF37, double 0x3F885D4D612E4A86, double 0x3F8552805E7B3072, double 0x3F82F4871B12AB64, double 0x3F810F9D4C0743A7, double 0x3F7F0593088014F8, double 0x3F7C7018733AA9C6, double 0x3F7A40514700F36C, double 0x3F786076C002D4A8, double 0x3F76C08F6F194A10, double 0x3F75549F7DD113BB, double 0x3F74137C74DA35F2, double 0x3F72F604FF627D78, double 0x3F71F697DD857D8E, double 0x3F7110B3ED261FB3, double 0x3F7040B3999E0E2A, double 0x3F6F0735F77A882F, double 0x3F6DADE5F5C049C9, double 0x3F6C715B494F1B2A, double 0x3F6B4E224E78A0FD, double 0x3F6A414F4A0D846C, double 0x3F6948654042BCD0, double 0x3F6861422F5D68C3, double 0x3F678A0F61376D25, double 0x3F66C134DF6E3D2B]
define double @_stirling_correction(i64 %0) {
%2 = alloca double
%3 = alloca i64
%4 = alloca double
%5 = alloca double
store i64 %0, i64* %3
%6 = load i64, i64* %3
%7 = icmp sgt i64 %6, 30
br i1 %7, label %8, label %22
8: ; preds = %1
%9 = load i64, i64* %3
%10 = sitofp i64 %9 to double
%11 = fdiv double 1.000000e+00, %10
store double %11, double* %4
%12 = load double, double* %4
%13 = call double @_sqr(double %12)
store double %13, double* %5
%14 = load double, double* %4
%15 = load double, double* %5
%16 = load double, double* %5
%17 = load double, double* %5
%18 = call double @llvm.fmuladd.f64(double %17, double 0xBF43813813813814, double 0x3F4A01A01A01A01A)
%19 = call double @llvm.fmuladd.f64(double %16, double %18, double 0xBF66C16C16C16C17)
%20 = call double @llvm.fmuladd.f64(double %15, double %19, double 0x3FB5555555555555)
%21 = fmul double %14, %20
store double %21, double* %2
br label %26
22: ; preds = %1
%23 = load i64, i64* %3
%24 = getelementptr inbounds [31 x double], [31 x double]* @_stirling_correction.c, i64 0, i64 %23
%25 = load double, double* %24
store double %25, double* %2
br label %26
26: ; preds = %22, %8
%27 = load double, double* %2
ret double %27
}

LLVM IR (-O2):
@_stirling_correction.c = internal unnamed_addr constant [31 x double] [double 0.000000e+00, double 0x3FB4C071BCDA0A5B, double 0x3FA52A9B923EA648, double 0x3F9C579A268D80B3, double 0x3F954A2662FD78A8, double 0x3F910B4E513FCBEC, double 0x3F8C6B167BEBDF37, double 0x3F885D4D612E4A86, double 0x3F8552805E7B3072, double 0x3F82F4871B12AB64, double 0x3F810F9D4C0743A7, double 0x3F7F0593088014F8, double 0x3F7C7018733AA9C6, double 0x3F7A40514700F36C, double 0x3F786076C002D4A8, double 0x3F76C08F6F194A10, double 0x3F75549F7DD113BB, double 0x3F74137C74DA35F2, double 0x3F72F604FF627D78, double 0x3F71F697DD857D8E, double 0x3F7110B3ED261FB3, double 0x3F7040B3999E0E2A, double 0x3F6F0735F77A882F, double 0x3F6DADE5F5C049C9, double 0x3F6C715B494F1B2A, double 0x3F6B4E224E78A0FD, double 0x3F6A414F4A0D846C, double 0x3F6948654042BCD0, double 0x3F6861422F5D68C3, double 0x3F678A0F61376D25, double 0x3F66C134DF6E3D2B]
define double @_stirling_correction(i64 %0) {
%2 = icmp sgt i64 %0, 30
br i1 %2, label %3, label %11
3: ; preds = %1
%4 = sitofp i64 %0 to double
%5 = fdiv double 1.000000e+00, %4
%6 = tail call double @_sqr(double %5)
%7 = tail call double @llvm.fmuladd.f64(double %6, double 0xBF43813813813814, double 0x3F4A01A01A01A01A)
%8 = tail call double @llvm.fmuladd.f64(double %6, double %7, double 0xBF66C16C16C16C17)
%9 = tail call double @llvm.fmuladd.f64(double %6, double %8, double 0x3FB5555555555555)
%10 = fmul double %5, %9
br label %14
11: ; preds = %1
%12 = getelementptr inbounds [31 x double], [31 x double]* @_stirling_correction.c, i64 0, i64 %0
%13 = load double, double* %12
br label %14
14: ; preds = %11, %3
%15 = phi double [ %10, %3 ], [ %13, %11 ]
ret double %15
}