double stirlerr(int n) {
  const static double sferr[16] = {0.0,
                                   0.0810614667953272582196702,
                                   0.0413406959554092940938221,
                                   0.02767792568499833914878929,
                                   0.02079067210376509311152277,
                                   0.01664469118982119216319487,
                                   0.01387612882307074799874573,
                                   0.01189670994589177009505572,
                                   0.010411265261972096497478567,
                                   0.009255462182712732917728637,
                                   0.008330563433362871256469318,
                                   0.007573675487951840794972024,
                                   0.006942840107209529865664152,
                                   0.006408994188004207068439631,
                                   0.005951370112758847735624416,
                                   0.005554733551962801371038690};
  if (n <= 15) {
    return (sferr[n]);
  }
  double nn = (double)n * (double)n;
  if (n > 500)
    return ((0.083333333333333333333 - 0.00277777777777777777778 / nn) /
            (double)n);
  if (n > 80)
    return (
        (0.083333333333333333333 -
         (0.00277777777777777777778 - 0.00079365079365079365079365 / nn) / nn) /
        (double)n);
  if (n > 35)
    return ((0.083333333333333333333 -
             (0.00277777777777777777778 - (0.00079365079365079365079365 -
                                           0.000595238095238095238095238 / nn) /
                                              nn) /
                 nn) /
            (double)n);
  return ((0.083333333333333333333 -
           (0.00277777777777777777778 - (0.00079365079365079365079365 -
                                         (0.000595238095238095238095238 -
                                          0.0008417508417508417508417508 / nn) /
                                             nn) /
                                            nn) /
               nn) /
          (double)n);
}


x86 assembly (clang, -O0):
<stirlerr>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
cmpl   $0xf,-0xc(%rbp)
jg     112b <stirlerr+0x2b>
movslq -0xc(%rbp),%rcx
lea    0xf14(%rip),%rax
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1270 <stirlerr+0x170>
cvtsi2sdl -0xc(%rbp),%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
cmpl   $0x1f4,-0xc(%rbp)
jle    1177 <stirlerr+0x77>
movsd  0xeb5(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
movsd  0xea0(%rip),%xmm0
subsd  %xmm1,%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1270 <stirlerr+0x170>
cmpl   $0x50,-0xc(%rbp)
jle    11be <stirlerr+0xbe>
movsd  0xe87(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  0xe72(%rip),%xmm1
subsd  %xmm0,%xmm1
divsd  -0x18(%rbp),%xmm1
movsd  0xe59(%rip),%xmm0
subsd  %xmm1,%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1270 <stirlerr+0x170>
cmpl   $0x23,-0xc(%rbp)
jle    1216 <stirlerr+0x116>
movsd  0xe48(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
movsd  0xe33(%rip),%xmm0
subsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  0xe1a(%rip),%xmm1
subsd  %xmm0,%xmm1
divsd  -0x18(%rbp),%xmm1
movsd  0xe01(%rip),%xmm0
subsd  %xmm1,%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1270 <stirlerr+0x170>
movsd  0xe02(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  0xded(%rip),%xmm1
subsd  %xmm0,%xmm1
divsd  -0x18(%rbp),%xmm1
movsd  0xdd4(%rip),%xmm0
subsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  0xdbb(%rip),%xmm1
subsd  %xmm0,%xmm1
divsd  -0x18(%rbp),%xmm1
movsd  0xda2(%rip),%xmm0
subsd  %xmm1,%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<stirlerr>:
cmp    $0xf,%edi
jg     1115 <stirlerr+0x15>
movslq %edi,%rax
lea    0xf31(%rip),%rcx
movsd  (%rcx,%rax,8),%xmm0
ret
cvtsi2sd %edi,%xmm1
movapd %xmm1,%xmm0
mulsd  %xmm1,%xmm0
cmp    $0x1f4,%edi
jbe    1133 <stirlerr+0x33>
movsd  0xecf(%rip),%xmm2
jmp    119d <stirlerr+0x9d>
cmp    $0x51,%edi
jb     114e <stirlerr+0x4e>
movsd  0xee8(%rip),%xmm2
divsd  %xmm0,%xmm2
addsd  0xeb4(%rip),%xmm2
jmp    119d <stirlerr+0x9d>
cmp    $0x24,%edi
jb     1169 <stirlerr+0x69>
movsd  0xec5(%rip),%xmm3
divsd  %xmm0,%xmm3
addsd  0xeb1(%rip),%xmm3
jmp    118d <stirlerr+0x8d>
movsd  0xe97(%rip),%xmm2
divsd  %xmm0,%xmm2
addsd  0xe93(%rip),%xmm2
divsd  %xmm0,%xmm2
movsd  0xe8f(%rip),%xmm3
subsd  %xmm2,%xmm3
divsd  %xmm0,%xmm3
movsd  0xe67(%rip),%xmm2
subsd  %xmm3,%xmm2
divsd  %xmm0,%xmm2
movsd  0xe87(%rip),%xmm0
subsd  %xmm2,%xmm0
divsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
@stirlerr.sferr = internal constant [16 x double] [double 0.000000e+00, double 0x3FB4C071BCDA0A5B, double 0x3FA52A9B923EA649, double 0x3F9C579A268D80B3, double 0x3F954A2662FD78A9, double 0x3F910B4E513FCBED, double 0x3F8C6B167BEBDF36, double 0x3F885D4D612E4A86, double 0x3F8552805E7B3076, double 0x3F82F4871B12AB64, double 0x3F810F9D4C0743A7, double 0x3F7F0593088014F8, double 0x3F7C7018733AA9C6, double 0x3F7A40514700F36C, double 0x3F786076C002D4A7, double 0x3F76C08F6F194A10]
define double @stirlerr(i32 %0) {
%2 = alloca double
%3 = alloca i32
%4 = alloca double
store i32 %0, i32* %3
%5 = load i32, i32* %3
%6 = icmp sle i32 %5, 15
br i1 %6, label %7, label %12
7: ; preds = %1
%8 = load i32, i32* %3
%9 = sext i32 %8 to i64
%10 = getelementptr inbounds [16 x double], [16 x double]* @stirlerr.sferr, i64 0, i64 %9
%11 = load double, double* %10
store double %11, double* %2
br label %72
12: ; preds = %1
%13 = load i32, i32* %3
%14 = sitofp i32 %13 to double
%15 = load i32, i32* %3
%16 = sitofp i32 %15 to double
%17 = fmul double %14, %16
store double %17, double* %4
%18 = load i32, i32* %3
%19 = icmp sgt i32 %18, 500
br i1 %19, label %20, label %27
20: ; preds = %12
%21 = load double, double* %4
%22 = fdiv double 0x3F66C16C16C16C17, %21
%23 = fsub double 0x3FB5555555555555, %22
%24 = load i32, i32* %3
%25 = sitofp i32 %24 to double
%26 = fdiv double %23, %25
store double %26, double* %2
br label %72
27: ; preds = %12
%28 = load i32, i32* %3
%29 = icmp sgt i32 %28, 80
br i1 %29, label %30, label %40
30: ; preds = %27
%31 = load double, double* %4
%32 = fdiv double 0x3F4A01A01A01A01A, %31
%33 = fsub double 0x3F66C16C16C16C17, %32
%34 = load double, double* %4
%35 = fdiv double %33, %34
%36 = fsub double 0x3FB5555555555555, %35
%37 = load i32, i32* %3
%38 = sitofp i32 %37 to double
%39 = fdiv double %36, %38
store double %39, double* %2
br label %72
40: ; preds = %27
%41 = load i32, i32* %3
%42 = icmp sgt i32 %41, 35
br i1 %42, label %43, label %56
43: ; preds = %40
%44 = load double, double* %4
%45 = fdiv double 0x3F43813813813814, %44
%46 = fsub double 0x3F4A01A01A01A01A, %45
%47 = load double, double* %4
%48 = fdiv double %46, %47
%49 = fsub double 0x3F66C16C16C16C17, %48
%50 = load double, double* %4
%51 = fdiv double %49, %50
%52 = fsub double 0x3FB5555555555555, %51
%53 = load i32, i32* %3
%54 = sitofp i32 %53 to double
%55 = fdiv double %52, %54
store double %55, double* %2
br label %72
56: ; preds = %40
%57 = load double, double* %4
%58 = fdiv double 0x3F4B951E2B18FF23, %57
%59 = fsub double 0x3F43813813813814, %58
%60 = load double, double* %4
%61 = fdiv double %59, %60
%62 = fsub double 0x3F4A01A01A01A01A, %61
%63 = load double, double* %4
%64 = fdiv double %62, %63
%65 = fsub double 0x3F66C16C16C16C17, %64
%66 = load double, double* %4
%67 = fdiv double %65, %66
%68 = fsub double 0x3FB5555555555555, %67
%69 = load i32, i32* %3
%70 = sitofp i32 %69 to double
%71 = fdiv double %68, %70
store double %71, double* %2
br label %72
72: ; preds = %56, %43, %30, %20, %7
%73 = load double, double* %2
ret double %73
}

LLVM IR (-O2):
@stirlerr.sferr = internal unnamed_addr constant [16 x double] [double 0.000000e+00, double 0x3FB4C071BCDA0A5B, double 0x3FA52A9B923EA649, double 0x3F9C579A268D80B3, double 0x3F954A2662FD78A9, double 0x3F910B4E513FCBED, double 0x3F8C6B167BEBDF36, double 0x3F885D4D612E4A86, double 0x3F8552805E7B3076, double 0x3F82F4871B12AB64, double 0x3F810F9D4C0743A7, double 0x3F7F0593088014F8, double 0x3F7C7018733AA9C6, double 0x3F7A40514700F36C, double 0x3F786076C002D4A7, double 0x3F76C08F6F194A10]
define double @stirlerr(i32 %0) {
%2 = icmp slt i32 %0, 16
br i1 %2, label %3, label %7
3: ; preds = %1
%4 = sext i32 %0 to i64
%5 = getelementptr inbounds [16 x double], [16 x double]* @stirlerr.sferr, i64 0, i64 %4
%6 = load double, double* %5
br label %35
7: ; preds = %1
%8 = sitofp i32 %0 to double
%9 = fmul double %8, %8
%10 = icmp ugt i32 %0, 500
br i1 %10, label %30, label %11
11: ; preds = %7
%12 = icmp ugt i32 %0, 80
br i1 %12, label %13, label %16
13: ; preds = %11
%14 = fdiv double 0x3F4A01A01A01A01A, %9
%15 = fsub double 0x3F66C16C16C16C17, %14
br label %30
16: ; preds = %11
%17 = icmp ugt i32 %0, 35
br i1 %17, label %18, label %23
18: ; preds = %16
%19 = fdiv double 0x3F43813813813814, %9
%20 = fsub double 0x3F4A01A01A01A01A, %19
%21 = fdiv double %20, %9
%22 = fsub double 0x3F66C16C16C16C17, %21
br label %30
23: ; preds = %16
%24 = fdiv double 0x3F4B951E2B18FF23, %9
%25 = fsub double 0x3F43813813813814, %24
%26 = fdiv double %25, %9
%27 = fsub double 0x3F4A01A01A01A01A, %26
%28 = fdiv double %27, %9
%29 = fsub double 0x3F66C16C16C16C17, %28
br label %30
30: ; preds = %7, %23, %18, %13
%31 = phi double [ %15, %13 ], [ %22, %18 ], [ %29, %23 ], [ 0x3F66C16C16C16C17, %7 ]
%32 = fdiv double %31, %9
%33 = fsub double 0x3FB5555555555555, %32
%34 = fdiv double %33, %8
br label %35
35: ; preds = %30, %3
%36 = phi double [ %6, %3 ], [ %34, %30 ]
ret double %36
}