#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 */
long double expl(int);
long double powl(int, int);
double gamma(double N) {
  const long double SQRT2PI =
      2.5066282746310005024157652848110452530069867406099383;
  long double Z = (long double)N;
  long double Sc = powl((Z + 15), (Z + 0.5));
  Sc *= expl(-1.0 * (Z + 15));
  Sc /= Z;
  long double F = 1.0;
  long double Ck;
  long double Sum = SQRT2PI;
  for (int K = 1; K < 15; K++) {
    Z++;
    Ck = powl(15 - K, K - 0.5);
    Ck *= expl(15 - K);
    Ck /= F;
    Sum += (Ck / Z);
    F *= (-1.0 * K);
  }
  return (double)(Sum * Sc);
}


x86 assembly (clang, -O0):
<gamma>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
movsd  %xmm0,-0x8(%rbp)
fldl   0xeca(%rip)
fld    %st(0)
fstpt  -0xa8(%rbp)
fstpt  -0x20(%rbp)
fldl   -0x8(%rbp)
fstpt  -0x30(%rbp)
fldt   -0x30(%rbp)
flds   0xec0(%rip)
fld    %st(0)
fstpt  -0xb4(%rbp)
fadd   %st(1),%st
fnstcw -0x92(%rbp)
movzwl -0x92(%rbp),%eax
or     $0xc00,%eax
mov    %ax,-0x94(%rbp)
fldcw  -0x94(%rbp)
fistpl -0x7c(%rbp)
fldcw  -0x92(%rbp)
mov    -0x7c(%rbp),%edi
flds   0xe89(%rip)
faddp  %st,%st(1)
fnstcw -0x96(%rbp)
movzwl -0x96(%rbp),%eax
or     $0xc00,%eax
mov    %ax,-0x98(%rbp)
fldcw  -0x98(%rbp)
fistpl -0x80(%rbp)
fldcw  -0x96(%rbp)
mov    -0x80(%rbp),%esi
call   1030 <powl@plt>
fldt   -0xb4(%rbp)
fxch   %st(1)
fstpt  -0x40(%rbp)
fldt   -0x30(%rbp)
faddp  %st,%st(1)
fchs
fnstcw -0x9a(%rbp)
movzwl -0x9a(%rbp),%eax
or     $0xc00,%eax
mov    %ax,-0x9c(%rbp)
fldcw  -0x9c(%rbp)
fistpl -0x78(%rbp)
fldcw  -0x9a(%rbp)
mov    -0x78(%rbp),%edi
call   1040 <expl@plt>
fldt   -0xa8(%rbp)
fldt   -0x40(%rbp)
fmulp  %st,%st(2)
fxch   %st(1)
fstpt  -0x40(%rbp)
fldt   -0x30(%rbp)
fldt   -0x40(%rbp)
fdivp  %st,%st(1)
fstpt  -0x40(%rbp)
fld1
fstpt  -0x50(%rbp)
fstpt  -0x70(%rbp)
movl   $0x1,-0x74(%rbp)
cmpl   $0xf,-0x74(%rbp)
jge    12d0 <gamma+0x1b0>
fldt   -0x30(%rbp)
fld1
faddp  %st,%st(1)
fstpt  -0x30(%rbp)
mov    -0x74(%rbp),%eax
mov    $0xf,%edi
mov    %edi,-0xb8(%rbp)
sub    %eax,%edi
cvtsi2sd %eax,%xmm0
movsd  0xdaf(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%esi
call   1030 <powl@plt>
mov    -0xb8(%rbp),%edi
fstpt  -0x60(%rbp)
mov    -0x74(%rbp),%eax
sub    %eax,%edi
call   1040 <expl@plt>
fldt   -0x60(%rbp)
fmulp  %st,%st(1)
fstpt  -0x60(%rbp)
fldt   -0x50(%rbp)
fldt   -0x60(%rbp)
fdivp  %st,%st(1)
fstpt  -0x60(%rbp)
fldt   -0x60(%rbp)
fldt   -0x30(%rbp)
fdivrp %st,%st(1)
fldt   -0x70(%rbp)
faddp  %st,%st(1)
fstpt  -0x70(%rbp)
cvtsi2sdl -0x74(%rbp),%xmm0
movaps 0xd78(%rip),%xmm1
pxor   %xmm1,%xmm0
movlpd %xmm0,-0x90(%rbp)
ff
fldl   -0x90(%rbp)
fldt   -0x50(%rbp)
fmulp  %st,%st(1)
fstpt  -0x50(%rbp)
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
jmp    1229 <gamma+0x109>
fldt   -0x70(%rbp)
fldt   -0x40(%rbp)
fmulp  %st,%st(1)
fstpl  -0x88(%rbp)
movsd  -0x88(%rbp),%xmm0
ff
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gamma>:
push   %rbx
sub    $0xa0,%rsp
movsd  %xmm0,0x50(%rsp)
fldl   0x50(%rsp)
fld    %st(0)
fadds  0xec6(%rip)
fld    %st(0)
fstpt  0x20(%rsp)
fld    %st(1)
fstpt  0x34(%rsp)
fnstcw 0xc(%rsp)
movzwl 0xc(%rsp),%eax
or     $0xc00,%eax
mov    %ax,0x12(%rsp)
fldcw  0x12(%rsp)
fistpl 0x18(%rsp)
fldcw  0xc(%rsp)
mov    0x18(%rsp),%edi
fadds  0xe95(%rip)
fnstcw 0xa(%rsp)
movzwl 0xa(%rsp),%eax
or     $0xc00,%eax
mov    %ax,0x10(%rsp)
fldcw  0x10(%rsp)
fistpl 0x14(%rsp)
fldcw  0xa(%rsp)
mov    0x14(%rsp),%esi
call   1030 <powl@plt>
fldt   0x20(%rsp)
fchs
fnstcw 0x8(%rsp)
movzwl 0x8(%rsp),%eax
or     $0xc00,%eax
mov    %ax,0xe(%rsp)
fldcw  0xe(%rsp)
fistpl 0x1c(%rsp)
fldcw  0x8(%rsp)
fstpt  0x64(%rsp)
mov    0x1c(%rsp),%edi
call   1040 <expl@plt>
fstpt  0x58(%rsp)
fld1
fldl   0xe33(%rip)
movsd  0xe33(%rip),%xmm0
mov    $0xe,%ebx
fldt   0x34(%rsp)
cs nopw 0x0(%rax,%rax,1)
movapd %xmm0,0x20(%rsp)
fxch   %st(2)
fstpt  0x88(%rsp)
fstpt  0x94(%rsp)
fld1
faddp  %st,%st(1)
fstpt  0x7c(%rsp)
movapd 0x20(%rsp),%xmm0
addsd  0xdfc(%rip),%xmm0
cvttsd2si %xmm0,%esi
mov    %ebx,%edi
call   1030 <powl@plt>
fstpt  0x70(%rsp)
mov    %ebx,%edi
call   1040 <expl@plt>
fldt   0x7c(%rsp)
fldt   0x88(%rsp)
fldt   0x94(%rsp)
fldt   0x70(%rsp)
fmulp  %st,%st(4)
fxch   %st(3)
fdiv   %st(1),%st
fdiv   %st(2),%st
faddp  %st,%st(3)
movaps 0x20(%rsp),%xmm0
xorps  0xdc2(%rip),%xmm0
movlps %xmm0,0x48(%rsp)
movapd 0x20(%rsp),%xmm0
fmull  0x48(%rsp)
addsd  0xd9b(%rip),%xmm0
add    $0xffffffff,%ebx
fxch   %st(2)
fxch   %st(1)
jne    11f0 <gamma+0xd0>
fstp   %st(2)
fstp   %st(1)
fldt   0x64(%rsp)
fldt   0x58(%rsp)
fmulp  %st,%st(1)
fldt   0x34(%rsp)
fdivrp %st,%st(1)
fmulp  %st,%st(1)
fstpl  0x40(%rsp)
movsd  0x40(%rsp),%xmm0
add    $0xa0,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define double @gamma(double %0) {
%2 = alloca double
%3 = alloca x86_fp80
%4 = alloca x86_fp80
%5 = alloca x86_fp80
%6 = alloca x86_fp80
%7 = alloca x86_fp80
%8 = alloca x86_fp80
%9 = alloca i32
store double %0, double* %2
store x86_fp80 0xK4000A06C98FFB1383000, x86_fp80* %3
%10 = load double, double* %2
%11 = fpext double %10 to x86_fp80
store x86_fp80 %11, x86_fp80* %4
%12 = load x86_fp80, x86_fp80* %4
%13 = fadd x86_fp80 %12, 0xK4002F000000000000000
%14 = fptosi x86_fp80 %13 to i32
%15 = load x86_fp80, x86_fp80* %4
%16 = fadd x86_fp80 %15, 0xK3FFE8000000000000000
%17 = fptosi x86_fp80 %16 to i32
%18 = call x86_fp80 @powl(i32 %14, i32 %17)
store x86_fp80 %18, x86_fp80* %5
%19 = load x86_fp80, x86_fp80* %4
%20 = fadd x86_fp80 %19, 0xK4002F000000000000000
%21 = fmul x86_fp80 0xKBFFF8000000000000000, %20
%22 = fptosi x86_fp80 %21 to i32
%23 = call x86_fp80 @expl(i32 %22)
%24 = load x86_fp80, x86_fp80* %5
%25 = fmul x86_fp80 %24, %23
store x86_fp80 %25, x86_fp80* %5
%26 = load x86_fp80, x86_fp80* %4
%27 = load x86_fp80, x86_fp80* %5
%28 = fdiv x86_fp80 %27, %26
store x86_fp80 %28, x86_fp80* %5
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %6
store x86_fp80 0xK4000A06C98FFB1383000, x86_fp80* %8
store i32 1, i32* %9
br label %29
29: ; preds = %61, %1
%30 = load i32, i32* %9
%31 = icmp slt i32 %30, 15
br i1 %31, label %32, label %64
32: ; preds = %29
%33 = load x86_fp80, x86_fp80* %4
%34 = fadd x86_fp80 %33, 0xK3FFF8000000000000000
store x86_fp80 %34, x86_fp80* %4
%35 = load i32, i32* %9
%36 = sub nsw i32 15, %35
%37 = load i32, i32* %9
%38 = sitofp i32 %37 to double
%39 = fsub double %38, 5.000000e-01
%40 = fptosi double %39 to i32
%41 = call x86_fp80 @powl(i32 %36, i32 %40)
store x86_fp80 %41, x86_fp80* %7
%42 = load i32, i32* %9
%43 = sub nsw i32 15, %42
%44 = call x86_fp80 @expl(i32 %43)
%45 = load x86_fp80, x86_fp80* %7
%46 = fmul x86_fp80 %45, %44
store x86_fp80 %46, x86_fp80* %7
%47 = load x86_fp80, x86_fp80* %6
%48 = load x86_fp80, x86_fp80* %7
%49 = fdiv x86_fp80 %48, %47
store x86_fp80 %49, x86_fp80* %7
%50 = load x86_fp80, x86_fp80* %7
%51 = load x86_fp80, x86_fp80* %4
%52 = fdiv x86_fp80 %50, %51
%53 = load x86_fp80, x86_fp80* %8
%54 = fadd x86_fp80 %53, %52
store x86_fp80 %54, x86_fp80* %8
%55 = load i32, i32* %9
%56 = sitofp i32 %55 to double
%57 = fmul double -1.000000e+00, %56
%58 = fpext double %57 to x86_fp80
%59 = load x86_fp80, x86_fp80* %6
%60 = fmul x86_fp80 %59, %58
store x86_fp80 %60, x86_fp80* %6
br label %61
61: ; preds = %32
%62 = load i32, i32* %9
%63 = add nsw i32 %62, 1
store i32 %63, i32* %9
br label %29
64: ; preds = %29
%65 = load x86_fp80, x86_fp80* %8
%66 = load x86_fp80, x86_fp80* %5
%67 = fmul x86_fp80 %65, %66
%68 = fptrunc x86_fp80 %67 to double
ret double %68
}

LLVM IR (-O2):
define double @gamma(double %0) {
%2 = fpext double %0 to x86_fp80
%3 = fadd x86_fp80 %2, 0xK4002F000000000000000
%4 = fptosi x86_fp80 %3 to i32
%5 = fadd x86_fp80 %2, 0xK3FFE8000000000000000
%6 = fptosi x86_fp80 %5 to i32
%7 = tail call x86_fp80 @powl(i32 %4, i32 %6)
%8 = fneg x86_fp80 %3
%9 = fptosi x86_fp80 %8 to i32
%10 = tail call x86_fp80 @expl(i32 %9)
br label %16
11: ; preds = %16
%12 = fmul x86_fp80 %7, %10
%13 = fdiv x86_fp80 %12, %2
%14 = fmul x86_fp80 %13, %31
%15 = fptrunc x86_fp80 %14 to double
ret double %15
16: ; preds = %1, %16
%17 = phi i32 [ 1, %1 ], [ %35, %16 ]
%18 = phi x86_fp80 [ 0xK4000A06C98FFB1383000, %1 ], [ %31, %16 ]
%19 = phi x86_fp80 [ %2, %1 ], [ %21, %16 ]
%20 = phi x86_fp80 [ 0xK3FFF8000000000000000, %1 ], [ %34, %16 ]
%21 = fadd x86_fp80 %19, 0xK3FFF8000000000000000
%22 = sub nuw nsw i32 15, %17
%23 = sitofp i32 %17 to double
%24 = fadd double %23, -5.000000e-01
%25 = fptosi double %24 to i32
%26 = tail call x86_fp80 @powl(i32 %22, i32 %25)
%27 = tail call x86_fp80 @expl(i32 %22)
%28 = fmul x86_fp80 %26, %27
%29 = fdiv x86_fp80 %28, %20
%30 = fdiv x86_fp80 %29, %21
%31 = fadd x86_fp80 %18, %30
%32 = fneg double %23
%33 = fpext double %32 to x86_fp80
%34 = fmul x86_fp80 %20, %33
%35 = add nuw nsw i32 %17, 1
%36 = icmp eq i32 %35, 15
br i1 %36, label %11, label %16
}