#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 log(double);
double logfactorial(unsigned k) {
  static const double logfact[100] = {
      0.0000000000000000,   0.0000000000000000,   0.6931471805599453,
      1.7917594692280550,   3.1780538303479456,   4.7874917427820460,
      6.5792512120101010,   8.5251613610654143,   10.6046029027452502,
      12.8018274800814696,  15.1044125730755153,  17.5023078458738858,
      19.9872144956618861,  22.5521638531234229,  25.1912211827386815,
      27.8992713838408916,  30.6718601060806728,  33.5050734501368889,
      36.3954452080330536,  39.3398841871994940,  42.3356164607534850,
      45.3801388984769080,  48.4711813518352239,  51.6066755677643736,
      54.7847293981123192,  58.0036052229805199,  61.2617017610020020,
      64.5575386270063311,  67.8897431371815350,  71.2570389671680090,
      74.6582363488301644,  78.0922235533153106,  81.5579594561150372,
      85.0544670175815174,  88.5808275421976788,  92.1361756036870925,
      95.7196945421432025,  99.3306124547874269,  102.9681986145138126,
      106.6317602606434591, 110.3206397147573954, 114.0342117814617032,
      117.7718813997450715, 121.5330815154386340, 125.3172711493568951,
      129.1239336391272149, 132.9525750356163099, 136.8027226373263685,
      140.6739236482342594, 144.5657439463448860, 148.4777669517730321,
      152.4095925844973578, 156.3608363030787852, 160.3311282166309070,
      164.3201122631951814, 168.3274454484276523, 172.3527971391628016,
      176.3958484069973517, 180.4562914175437711, 184.5338288614494905,
      188.6281734236715912, 192.7390472878449024, 196.8661816728899940,
      201.0093163992815267, 205.1681994826411985, 209.3425867525368356,
      213.5322414945632612, 217.7369341139542273, 221.9564418191303340,
      226.1905483237275933, 230.4390435657769523, 234.7017234428182677,
      238.9783895618343230, 243.2688490029827142, 247.5729140961868839,
      251.8904022097231944, 256.2211355500095255, 260.5649409718632093,
      264.9216497985528010, 269.2910976510198225, 273.6731242856937041,
      278.0675734403661429, 282.4742926876303960, 286.8931332954269940,
      291.3239500942703076, 295.7666013507606240, 300.2209486470141318,
      304.6868567656687155, 309.1641935801469219, 313.6528299498790618,
      318.1526396202093268, 322.6634991267261769, 327.1852877037752172,
      331.7178871969284731, 336.2611819791984770, 340.8150588707990179,
      345.3794070622668541, 349.9541180407702369, 354.5390855194408088,
      359.1342053695753988};
  double s, y;
  if (k < 100)
    return logfact[k];
  y = k + 1.0;
  s = y + 2.269488974204959960;
  s = y + 1.517473649153287398 / s;
  s = y + 1.011523068126841711 / s;
  s = y + 0.525606469002695417 / s;
  s = y + 0.252380952380952380 / s;
  s = y + 0.033333333333333333 / s;
  s = 0.083333333333333333 / s;
  s = s + 0.91893853320467 - y + (y - 0.5) * log(y);
  return s;
}


x86 assembly (clang, -O0):
<logfactorial>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0xc(%rbp)
cmpl   $0x64,-0xc(%rbp)
jae    1140 <logfactorial+0x30>
mov    -0xc(%rbp),%eax
mov    %eax,%ecx
lea    0xf1f(%rip),%rax
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    125f <logfactorial+0x14f>
mov    -0xc(%rbp),%eax
cvtsi2sd %rax,%xmm0
movsd  0xef8(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xedf(%rip),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xec0(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe9d(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe7a(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe57(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe34(%rip),%xmm1
divsd  -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xe16(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xdfc(%rip),%xmm0
addsd  -0x18(%rbp),%xmm0
subsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xdd8(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1030 <log@plt>
movsd  -0x30(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x28(%rbp),%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<logfactorial>:
sub    $0x18,%rsp
mov    %edi,%eax
cmp    $0x63,%edi
ja     112c <logfactorial+0x1c>
lea    0xf2e(%rip),%rcx
movsd  (%rcx,%rax,8),%xmm0
add    $0x18,%rsp
ret
cvtsi2sd %rax,%xmm0
addsd  0xec7(%rip),%xmm0
movsd  0xec7(%rip),%xmm1
addsd  %xmm0,%xmm1
movsd  0xec3(%rip),%xmm2
divsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
movsd  0xebb(%rip),%xmm1
divsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  0xeb3(%rip),%xmm2
divsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
movsd  0xeab(%rip),%xmm1
divsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  0xea3(%rip),%xmm2
divsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
movsd  0xe9b(%rip),%xmm1
divsd  %xmm2,%xmm1
addsd  0xe97(%rip),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
movsd  0xe8d(%rip),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
call   1030 <log@plt>
mulsd  0x8(%rsp),%xmm0
addsd  0x10(%rsp),%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
@logfactorial.logfact = internal constant [100 x double] [double 0.000000e+00, double 0.000000e+00, double 0x3FE62E42FEFA39EF, double 0x3FFCAB0BFA2A2002, double 0x40096CA77C922CF9, double 0x401326643C4479C9, double 0x401A51273ACF01CA, double 0x40210CE1F32DCC30, double 0x4025358E82FCB70D, double 0x40299A8921A7F7CF, double 0x402E357590954D15, double 0x403180973F3A8D74, double 0x4033FCBA16D50143, double 0x40368D5A9C3B32CE, double 0x403930F3DF162A42, double 0x403BE636A63FD346, double 0x403EABFF061F1A84, double 0x4040C0A63F2F353A, double 0x4042329DF2D5EE52, double 0x4043AB8153363985, double 0x40452AF57AED77BE, double 0x4046B0A8643472A9, double 0x40483C4FABA84F06, double 0x4049CDA78B856A45, double 0x404B6472034E8D14, double 0x404D007622CD65E7, double 0x404EA17F717C6794, double 0x405023AEB67E4FEF, double 0x4050F8F18D330240, double 0x4051D07353917231, double 0x4052AA208B59D0E5, double 0x405385E6FD9E5A40, double 0x405463B59B942084, double 0x4055437C633ACE4A, double 0x4056252C474896BA, double 0x405708B719E11658, double 0x4057EE0F79B26758, double 0x4058D528C1243D96, double 0x4059BDF6F75257A3, double 0x405AA86EC2969812, double 0x405B94855C702BA2, double 0x405C8230869CA105, double 0x405D7166813E12EE, double 0x405E621E01EEBA4F, double 0x405F544E2BA69CF1, double 0x406023F743ADDD9F, double 0x40609E7B7EA41EA9, double 0x406119AFE762626B, double 0x40619590C853A559, double 0x4062121A930C6EC3, double 0x40628F49DDEB1F31, double 0x40630D1B61E86335, double 0x40638B8BF8931DDB, double 0x40640A989A33A6CD, double 0x40648A3E5C12AF19, double 0x40650A7A6EE08711, double 0x40658B4A1D39DA73, double 0x40660CAACA474746, double 0x40668E99F0757979, double 0x406711152043B2C4, double 0x40679419FF26DC59, double 0x406817A6467F6FB9, double 0x40689BB7C2A0AEA1, double 0x4069204C51E7C761, double 0x4069A561E3E1A4BD, double 0x406A2AF6787E4609, double 0x406AB1081F509726, double 0x406B3794F6D9D7AF, double 0x406BBE9B2BDFB621, double 0x406C4618F8CC56F7, double 0x406CCE0CA5179100, double 0x406D567484B8B7B6, double 0x406DDF4EF7A05A70, double 0x406E689A69396BEF, double 0x406EF2554FF15148, double 0x406F7C7E2CC66183, double 0x40700389C56E3462, double 0x40704909FF8B652B, double 0x40708EBF13DBF263, double 0x4070D4A85602B129, double 0x40711AC51DF8932A, double 0x40716114C7E34736, double 0x4071A796B3EDE1AC, double 0x4071EE4A46236D3E, double 0x4072352EE64B46D5, double 0x40727C43FFC72962, double 0x4072C3890172D057, double 0x40730AFD5D851956, double 0x407352A089728F1B, double 0x40739A71FDD14947, double 0x4073E271363E0DF7, double 0x40742A9DB142A36A, double 0x407472F6F03D410C, double 0x4074BB7C77491066, double 0x4075042DCD27AF64, double 0x40754D0A7B2BA658, double 0x407596120D23C4EC, double 0x4075DF4411475A1C, double 0x407628A018233BED, double 0x40767225B4879462]
define double @logfactorial(i32 %0) {
%2 = alloca double
%3 = alloca i32
%4 = alloca double
%5 = alloca double
store i32 %0, i32* %3
%6 = load i32, i32* %3
%7 = icmp ult i32 %6, 100
br i1 %7, label %8, label %13
8: ; preds = %1
%9 = load i32, i32* %3
%10 = zext i32 %9 to i64
%11 = getelementptr inbounds [100 x double], [100 x double]* @logfactorial.logfact, i64 0, i64 %10
%12 = load double, double* %11
store double %12, double* %2
br label %51
13: ; preds = %1
%14 = load i32, i32* %3
%15 = uitofp i32 %14 to double
%16 = fadd double %15, 1.000000e+00
store double %16, double* %5
%17 = load double, double* %5
%18 = fadd double %17, 0x400227E9D5D6BE3D
store double %18, double* %4
%19 = load double, double* %5
%20 = load double, double* %4
%21 = fdiv double 0x3FF8479272FA7B7C, %20
%22 = fadd double %19, %21
store double %22, double* %4
%23 = load double, double* %5
%24 = load double, double* %4
%25 = fdiv double 0x3FF02F32D00C11E1, %24
%26 = fadd double %23, %25
store double %26, double* %4
%27 = load double, double* %5
%28 = load double, double* %4
%29 = fdiv double 0x3FE0D1C4A85DD7FA, %28
%30 = fadd double %27, %29
store double %30, double* %4
%31 = load double, double* %5
%32 = load double, double* %4
%33 = fdiv double 0x3FD0270270270270, %32
%34 = fadd double %31, %33
store double %34, double* %4
%35 = load double, double* %5
%36 = load double, double* %4
%37 = fdiv double 0x3FA1111111111111, %36
%38 = fadd double %35, %37
store double %38, double* %4
%39 = load double, double* %4
%40 = fdiv double 0x3FB5555555555555, %39
store double %40, double* %4
%41 = load double, double* %4
%42 = fadd double %41, 0x3FED67F1C864BE9C
%43 = load double, double* %5
%44 = fsub double %42, %43
%45 = load double, double* %5
%46 = fsub double %45, 5.000000e-01
%47 = load double, double* %5
%48 = call double @log(double %47)
%49 = call double @llvm.fmuladd.f64(double %46, double %48, double %44)
store double %49, double* %4
%50 = load double, double* %4
store double %50, double* %2
br label %51
51: ; preds = %13, %8
%52 = load double, double* %2
ret double %52
}

LLVM IR (-O2):
@logfactorial.logfact = internal unnamed_addr constant [100 x double] [double 0.000000e+00, double 0.000000e+00, double 0x3FE62E42FEFA39EF, double 0x3FFCAB0BFA2A2002, double 0x40096CA77C922CF9, double 0x401326643C4479C9, double 0x401A51273ACF01CA, double 0x40210CE1F32DCC30, double 0x4025358E82FCB70D, double 0x40299A8921A7F7CF, double 0x402E357590954D15, double 0x403180973F3A8D74, double 0x4033FCBA16D50143, double 0x40368D5A9C3B32CE, double 0x403930F3DF162A42, double 0x403BE636A63FD346, double 0x403EABFF061F1A84, double 0x4040C0A63F2F353A, double 0x4042329DF2D5EE52, double 0x4043AB8153363985, double 0x40452AF57AED77BE, double 0x4046B0A8643472A9, double 0x40483C4FABA84F06, double 0x4049CDA78B856A45, double 0x404B6472034E8D14, double 0x404D007622CD65E7, double 0x404EA17F717C6794, double 0x405023AEB67E4FEF, double 0x4050F8F18D330240, double 0x4051D07353917231, double 0x4052AA208B59D0E5, double 0x405385E6FD9E5A40, double 0x405463B59B942084, double 0x4055437C633ACE4A, double 0x4056252C474896BA, double 0x405708B719E11658, double 0x4057EE0F79B26758, double 0x4058D528C1243D96, double 0x4059BDF6F75257A3, double 0x405AA86EC2969812, double 0x405B94855C702BA2, double 0x405C8230869CA105, double 0x405D7166813E12EE, double 0x405E621E01EEBA4F, double 0x405F544E2BA69CF1, double 0x406023F743ADDD9F, double 0x40609E7B7EA41EA9, double 0x406119AFE762626B, double 0x40619590C853A559, double 0x4062121A930C6EC3, double 0x40628F49DDEB1F31, double 0x40630D1B61E86335, double 0x40638B8BF8931DDB, double 0x40640A989A33A6CD, double 0x40648A3E5C12AF19, double 0x40650A7A6EE08711, double 0x40658B4A1D39DA73, double 0x40660CAACA474746, double 0x40668E99F0757979, double 0x406711152043B2C4, double 0x40679419FF26DC59, double 0x406817A6467F6FB9, double 0x40689BB7C2A0AEA1, double 0x4069204C51E7C761, double 0x4069A561E3E1A4BD, double 0x406A2AF6787E4609, double 0x406AB1081F509726, double 0x406B3794F6D9D7AF, double 0x406BBE9B2BDFB621, double 0x406C4618F8CC56F7, double 0x406CCE0CA5179100, double 0x406D567484B8B7B6, double 0x406DDF4EF7A05A70, double 0x406E689A69396BEF, double 0x406EF2554FF15148, double 0x406F7C7E2CC66183, double 0x40700389C56E3462, double 0x40704909FF8B652B, double 0x40708EBF13DBF263, double 0x4070D4A85602B129, double 0x40711AC51DF8932A, double 0x40716114C7E34736, double 0x4071A796B3EDE1AC, double 0x4071EE4A46236D3E, double 0x4072352EE64B46D5, double 0x40727C43FFC72962, double 0x4072C3890172D057, double 0x40730AFD5D851956, double 0x407352A089728F1B, double 0x40739A71FDD14947, double 0x4073E271363E0DF7, double 0x40742A9DB142A36A, double 0x407472F6F03D410C, double 0x4074BB7C77491066, double 0x4075042DCD27AF64, double 0x40754D0A7B2BA658, double 0x407596120D23C4EC, double 0x4075DF4411475A1C, double 0x407628A018233BED, double 0x40767225B4879462]
define double @logfactorial(i32 %0) {
%2 = icmp ult i32 %0, 100
br i1 %2, label %3, label %7
3: ; preds = %1
%4 = zext i32 %0 to i64
%5 = getelementptr inbounds [100 x double], [100 x double]* @logfactorial.logfact, i64 0, i64 %4
%6 = load double, double* %5
br label %27
7: ; preds = %1
%8 = uitofp i32 %0 to double
%9 = fadd double %8, 1.000000e+00
%10 = fadd double %9, 0x400227E9D5D6BE3D
%11 = fdiv double 0x3FF8479272FA7B7C, %10
%12 = fadd double %9, %11
%13 = fdiv double 0x3FF02F32D00C11E1, %12
%14 = fadd double %9, %13
%15 = fdiv double 0x3FE0D1C4A85DD7FA, %14
%16 = fadd double %9, %15
%17 = fdiv double 0x3FD0270270270270, %16
%18 = fadd double %9, %17
%19 = fdiv double 0x3FA1111111111111, %18
%20 = fadd double %9, %19
%21 = fdiv double 0x3FB5555555555555, %20
%22 = fadd double %21, 0x3FED67F1C864BE9C
%23 = fsub double %22, %9
%24 = fadd double %9, -5.000000e-01
%25 = tail call double @log(double %9)
%26 = tail call double @llvm.fmuladd.f64(double %24, double %25, double %23)
br label %27
27: ; preds = %7, %3
%28 = phi double [ %6, %3 ], [ %26, %7 ]
ret double %28
}