# Math.lgamma and Math.gamma

**URL:** <https://www.ruby-forum.com/t/math-lgamma-and-math-gamma/128313>\
**Category:** Development\
**Created:** [February 6, 2008, 6:29pm UTC](https://www.ruby-forum.com/t/math-lgamma-and-math-gamma/128313 "2008-02-06T18:29:50Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tanaka\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c67d28/32.png) [@Tanaka\_A](https://www.ruby-forum.com/u/Tanaka_A)\
**Post date:** [February 6, 2008, 6:29pm UTC](https://www.ruby-forum.com/t/math-lgamma-and-math-gamma/128313/1 "2008-02-06T18:29:50Z")

</div>

e$B$U$H!“e(Blog2(nCm) e$B$N%0%i%U$r=q$$$F$\_$h$&$H;W$C$?$N$G$9$,!“e(BnCm  
e$B$N7W;;$K3,\>h$,I,MW$G!”$3$l$r$U$D$&$K7W;;$9$k$N$O%k!\<%W$,I,MWe(B  
e$B$G$+$J$jCY$/!”&#4X?t$,e(B  
(e$B@53N$K$O%\*!\<%P!\<%U%m!\<$rHr$1$kI,MW\>e!“e(B  
e$B&#4X?t$NBP?t$,e(B) e$B$”$l$P9bB.$K7W;;$G$-$k$N$K!"$H;DG0$J;W$$$r$7e(B  
e$B$^$7$?!#e(B

e$B$H$$$&$o$1$G!"e(B  
Math.gamma(x) =\> float  
Math.lgamma(x) =\> [float, sign\_of\_gamma\_x]  
e$B$H$$$&$N$r\<BAu$7$F$\_$?$s$G$9$,$I$&$G$7$g$&$+!#e(B

e$BM\_$7$+$C$?$N$Oe(B lgamma e$B$J$s$G$9$,!“e(Blgamma e$B$@$1$Ge(B gamma  
e$B$,$J$$e(B  
e$B$N$b$J$s$J$N$Ge(B gamma e$B$b\<BAu$7$F$”$j$^$9!#e(B

e$B;HMQ$9$k4X?t$Oe(B tgamma e$B$He(B lgamma\_r e$B$G$9!#e(B

tgamma e$B$Oe(B C99 e$B$GDj5A$5$l$F$^$9!#e(B

lgamma\_r e$B$O5,3J$K$“$j$^$;$s!#5,3J$K$”$k$N$Oe(B lgamma e$B$G!"$3$le(B  
e$B$O%9%l%C%I%;!\<%U$8$c$J$$$N$GHr$1$F!“e(Blgamma\_r  
e$B$r;H$C$F$$$^$9!#e(B  
lgamma\_r e$B$Oe(B GNU/Linux, NetBSD, Solaris e$B$J$I$K$”$j$^$9!#e(B

missing/tgamma.c e$B$O!Ve(BCe$B8@8l$K$h$k:G?7%"%k%4%j%:%`;vE5!W$Ne(B  
e$B%5%]!\<%H%Z!\<%8$Ne(B [『C言語による最新アルゴリズム事典』](http://oku.edu.mie-u.ac.jp/~okumura/algo/)  
e$B$+$i\<hF@$7$?e(B algo.tar.gz e$BFb$Ne(B gamma.c  
e$B$r85$K$7$F4X?tL\>$d%3%ae(B  
e$B%s%H$J$I$rD4@0$7$?$b$N$G$9!#e(B

missing/lgamma\_r.c e$B$Oe(B tgamma.c e$B$r$5$i$K$$$8$C$F:n$j$^$7$?!#e(B

algo.tar.gz e$BCf$Ne(B README e$B$Ke(B  
| e$B$4MxMQ$K$D$$$F$N@)8B$O$“$j$^$;$s!#$?$@$7%P%0$K$h$kB;32$Ne(B  
| e$BGe=~$J$I$K$O1~$8$+$M$^$9$N$G$4N;\>5$/$@$5$$!#e(B  
e$B$H$”$C$?$N$H!“$d$O$j!Ve(BCe$B8@8l$K$h$k:G?7%”%k%4%j%:%`;vE5!W$+$ie(B  
e$B$H$i$l$F$$$ke(B erf.c e$B$Ke(B public domain  
e$B$H=q$$$F$"$C$?$N$G!“e(B  
missing/tgamma.c, missing/lgamma\_r.c e$B$be(B public domain e$B$H$7$Fe(B  
e$B$”$j$^$9!#e(B

# Index: math.c

— math.c (revision 15384)  
+++ math.c (working copy)  
@@ -487,6 +487,42 @@ math\_erfc(VALUE obj, VALUE x)  
}

/\*

- 
  - call-seq:

- 
  - Math.gamma(x) =\> float

- 
  - 

- 
  - Calculates the gamma function of x.

- \*/
- 

+static VALUE  
+math\_gamma(VALUE obj, VALUE x)  
+{

- Need\_Float(x);
- return DOUBLE2NUM(tgamma(RFLOAT\_VALUE(x)));  
+}
- 

+/\*

- 
  - call-seq:

- 
  - Math.lgamma(x) =\> [float, -1 or 1]

- 
  - 

- 
  - Calculates the logarithmic gamma of x and

- 
  - the sign of gamma of x.

- 
  - 

- 
  - Math.lgamma(x) is same as

- 
  - [Math.log(Math.gamma(x)), Math.gamma(x) \< 0 ? -1 : 1]

- 
  - but avoid overflow by Math.gamma(x) for large x.

- \*/
- 

+static VALUE  
+math\_lgamma(VALUE obj, VALUE x)  
+{

- int sign;
- VALUE v;
- Need\_Float(x);
- v = DOUBLE2NUM(lgamma\_r(RFLOAT\_VALUE(x), &sign));
- return rb\_assoc\_new(v, INT2FIX(sign));  
+}
- 

+/\*

- The `Math` module contains module functions for basic

- trigonometric and transcendental functions. See class

- `Float` for a list of constants that  
@@ -541,4 +577,7 @@ Init\_Math(void)

- 
- rb\_define\_module\_function(rb\_mMath, “gamma”, math\_gamma, 1);
- rb\_define\_module\_function(rb\_mMath, “lgamma”, math\_lgamma, 1);  
}  
Index: include/ruby/missing.h  
===================================================================  
— include/ruby/missing.h (revision 15384)  
+++ include/ruby/missing.h (working copy)  
@@ -79,6 +79,14 @@ extern double erf(double);  
extern double erfc(double);  
#endif

+#ifndef HAVE\_TGAMMA  
+extern double tgamma(double);  
+#endif  
+  
+#ifndef HAVE\_LGAMMA\_R  
+extern double lgamma\_r(double, int \*);  
+#endif  
+  
#ifndef isinf

# ifndef HAVE\_ISINF

# if defined(HAVE\_FINITE) && defined(HAVE\_ISNAN)

# Index: configure.in

— configure.in (revision 15384)  
+++ configure.in (working copy)  
@@ -649,7 +649,8 @@ esac  
AC\_FUNC\_MEMCMP  
AC\_REPLACE\_FUNCS(dup2 memmove strerror strftime  
strchr strstr crypt flock vsnprintf\

- 

```
isnan finite isinf hypot acosh erf strlcpy strlcat)

```

- 

```
isnan finite isinf hypot acosh erf tgamma lgamma_r \

```

- 

```
            strlcpy strlcat)

```

# AC\_CHECK\_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd eaccess truncate chsize times utimes utimensat fcntl lockf lstat link symlink readlink Index: missing/tgamma.c

— missing/tgamma.c (revision 0)  
+++ missing/tgamma.c (revision 0)  
@@ -0,0 +1,49 @@  
+/\* tgamma.c - public domain implementation of error function  
tgamma(3m)  
+  
+reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten

- 

```
       (New Algorithm handbook in C language) (Gijyutsu hyouron

```

- 

```
       sha, Tokyo, 1991) [in Japanese]

```

- 

```
       http://oku.edu.mie-u.ac.jp/~okumura/algo/

```

+\*/  
+  
+/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

- gamma.c – Gamma function  
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
+#include \<math.h\>  
+#define PI 3.14159265358979324 /\* $\pi$ _/  
+#define LOG\_2PI 1.83787706640934548 /_ $\log 2\pi$ \*/  
+#define N 8
- 

+#define B0 1 /\* Bernoulli numbers _/  
+#define B1 (-1.0 / 2.0)  
+#define B2 ( 1.0 / 6.0)  
+#define B4 (-1.0 / 30.0)  
+#define B6 ( 1.0 / 42.0)  
+#define B8 (-1.0 / 30.0)  
+#define B10 ( 5.0 / 66.0)  
+#define B12 (-691.0 / 2730.0)  
+#define B14 ( 7.0 / 6.0)  
+#define B16 (-3617.0 / 510.0)  
+  
+static double  
+loggamma(double x) /_ the natural logarithm of the Gamma function. \*/  
+{

- double v, w;
- 
- v = 1;
- while (x \< N) { v \*= x; x++; }
- w = 1 / (x \* x);
- return ((((((((B16 / (16 \* 15)) \* w + (B14 / (14 \* 13))) \* w
- 

```
           + (B12 / (12 * 11))) * w + (B10 / (10 * 9))) * w

```

- 

```
           + (B8 / ( 8 * 7))) * w + (B6 / ( 6 * 5))) * w

```

- 

```
           + (B4 / ( 4 * 3))) * w + (B2 / ( 2 * 1))) / x

```

- 

```
           + 0.5 * LOG_2PI - log(v) - x + (x - 0.5) * log(x);

```

+}  
+  
+double tgamma(double x) /\* Gamma function \*/  
+{

- if (x \< 0)
- 

```
   return PI / (sin(PI * x) * exp(loggamma(1 - x)));

```

- return exp(loggamma(x));  
+}
- 

# Index: missing/lgamma\_r.c

— missing/lgamma\_r.c (revision 0)  
+++ missing/lgamma\_r.c (revision 0)  
@@ -0,0 +1,64 @@  
+/\* lgamma\_r.c - public domain implementation of error function  
lgamma\_r(3m)  
+  
+lgamma\_r() is based on gamma(). modified by Tanaka A…  
+  
+reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten

- 

```
       (New Algorithm handbook in C language) (Gijyutsu hyouron

```

- 

```
       sha, Tokyo, 1991) [in Japanese]

```

- 

```
       http://oku.edu.mie-u.ac.jp/~okumura/algo/

```

+\*/  
+  
+/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

- gamma.c – Gamma function  
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
+#include \<math.h\>  
+#define PI 3.14159265358979324 /\* $\pi$ _/  
+#define LOG\_2PI 1.83787706640934548 /_ $\log 2\pi$ _/  
+#define LOG\_PI 1.14472988584940017 /_ $\log\_e \pi$ \*/  
+#define N 8
- 

+#define B0 1 /\* Bernoulli numbers _/  
+#define B1 (-1.0 / 2.0)  
+#define B2 ( 1.0 / 6.0)  
+#define B4 (-1.0 / 30.0)  
+#define B6 ( 1.0 / 42.0)  
+#define B8 (-1.0 / 30.0)  
+#define B10 ( 5.0 / 66.0)  
+#define B12 (-691.0 / 2730.0)  
+#define B14 ( 7.0 / 6.0)  
+#define B16 (-3617.0 / 510.0)  
+  
+static double  
+loggamma(double x) /_ the natural logarithm of the Gamma function. \*/  
+{

- double v, w;
- 
- v = 1;
- while (x \< N) { v \*= x; x++; }
- w = 1 / (x \* x);
- return ((((((((B16 / (16 \* 15)) \* w + (B14 / (14 \* 13))) \* w
- 

```
           + (B12 / (12 * 11))) * w + (B10 / (10 * 9))) * w

```

- 

```
           + (B8 / ( 8 * 7))) * w + (B6 / ( 6 * 5))) * w

```

- 

```
           + (B4 / ( 4 * 3))) * w + (B2 / ( 2 * 1))) / x

```

- 

```
           + 0.5 * LOG_2PI - log(v) - x + (x - 0.5) * log(x);

```

+}  
+  
+/\* the natural logarithm of the absolute value of the Gamma function \*/  
+double  
+lgamma\_r(double x, int \*signp)  
+{

- if (x \< 0) {
- 

```
   double i, f, s;

```

- 

```
   f = modf(-x, &i);

```

- 

```
   if (f == 0.0) {

```

- 

```
       *signp = 1;

```

- 

```
       return 1.0/0.0;

```

- 

```
   }

```

- 

```
   *signp = (fmod(i, 2.0) != 0.0) ? 1 : -1;

```

- 

```
   s = sin(PI * x);

```

- 

```
   if (s < 0) s = -s;

```

- 

```
   return LOG_PI - log(s) - loggamma(1 - x);

```

- }
- \*signp = 1;
- return loggamma(x);  
+}  
Index: LEGAL  
===================================================================  
— LEGAL (revision 15384)  
+++ LEGAL (working copy)  
@@ -158,6 +158,8 @@ ext/digest/sha1/sha1.[ch]:  
These files are all under public domain.

missing/erf.c:  
+missing/tgamma.c:  
+missing/lgamma\_r.c:  
missing/crypt.c:  
missing/vsnprintf.c:

---

<div class="post-metadata">

**Author:** ![Tanaka\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c67d28/32.png) [@Tanaka\_A](https://www.ruby-forum.com/u/Tanaka_A)\
**Post date:** [February 7, 2008, 2:19am UTC](https://www.ruby-forum.com/t/math-lgamma-and-math-gamma/128313/2 "2008-02-07T02:19:58Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:33620] Math.lgamma and Math.gamma”  
on Thu, 7 Feb 2008 02:29:14 +0900, Tanaka A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|e$B$U$H!"e(Blog2(nCm) e$B$N%0%i%U$r=q$$$F$_$h$&$H;W$C$?$N$G$9$,!“e(BnCm  
|e$B$N7W;;$K3,\>h$,I,MW$G!”$3$l$r$U$D$&$K7W;;$9$k$N$O%k!\<%W$,I,MWe(B  
|e$B$G$+$J$jCY$/!“&#4X?t$,e(B (e$B@53N$K$O%\*!\<%P!\<%U%m!\<$rHr$1$kI,MW\>e!“e(B  
|e$B&#4X?t$NBP?t$,e(B) e$B$”$l$P9bB.$K7W;;$G$-$k$N$K!”$H;DG0$J;W$$$r$7e(B  
|e$B$^$7$?!#e(B  
|  
|e$B$H$$$&$o$1$G!"e(B  
| Math.gamma(x) =\> float  
| Math.lgamma(x) =\> [float, sign\_of\_gamma\_x]  
|e$B$H$$$&$N$r\<BAu$7$F$_$?$s$G$9$,$I$&$G$7$g$&$+!#e(B

e$B$$$$$s$8$c$J$$$G$7$g$&$+!#%3%\_%C%H$7$F$/$@$5$$!#e(B
