summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in1
-rw-r--r--math.c16
-rw-r--r--missing/tgamma.c21
3 files changed, 22 insertions, 16 deletions
diff --git a/configure.in b/configure.in
index 1ca8d142ac..76eb9accec 100644
--- a/configure.in
+++ b/configure.in
@@ -1317,6 +1317,7 @@ main()
ac_cv_func___builtin_setjmp=no
ac_cv_func_round=no
])
+ ac_cv_func_tgamma=no
AC_CHECK_TYPE([NET_LUID], [], [],
[@%:@include <winsock2.h>
@%:@include <iphlpapi.h>])
diff --git a/math.c b/math.c
index 245cdcfb01..570776baef 100644
--- a/math.c
+++ b/math.c
@@ -778,22 +778,6 @@ math_erfc(VALUE unused_obj, VALUE x)
return DBL2NUM(erfc(Get_Double(x)));
}
-#if defined _WIN32
-static inline double
-ruby_tgamma(const double d)
-{
- const double g = tgamma(d);
- if (isinf(g)) {
- if (d == 0.0 && signbit(d)) return -INFINITY;
- }
- if (isnan(g)) {
- if (!signbit(d)) return INFINITY;
- }
- return g;
-}
-#define tgamma(d) ruby_tgamma(d)
-#endif
-
#if defined LGAMMA_R_PM0_FIX
static inline double
ruby_lgamma_r(const double d, int *sign)
diff --git a/missing/tgamma.c b/missing/tgamma.c
index 9324e19ea1..6260e4f519 100644
--- a/missing/tgamma.c
+++ b/missing/tgamma.c
@@ -10,9 +10,25 @@ reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
gamma.c -- Gamma function
***********************************************************/
#include "ruby/config.h"
+#include "ruby/missing.h"
#include <math.h>
#include <errno.h>
+#ifdef _WIN32
+# include <float.h>
+# if !defined __MINGW32__ || defined __NO_ISOCEXT
+# ifndef isnan
+# define isnan(x) _isnan(x)
+# endif
+# ifndef isinf
+# define isinf(x) (!_finite(x) && !_isnan(x))
+# endif
+# ifndef finite
+# define finite(x) _finite(x)
+# endif
+# endif
+#endif
+
#ifndef HAVE_LGAMMA_R
#include <errno.h>
@@ -54,11 +70,16 @@ double tgamma(double x) /* Gamma function */
errno = ERANGE;
return 1/x < 0 ? -HUGE_VAL : HUGE_VAL;
}
+ if (isinf(x)) {
+ if (x < 0) goto domain_error;
+ return x;
+ }
if (x < 0) {
static double zero = 0.0;
double i, f;
f = modf(-x, &i);
if (f == 0.0) { /* Domain Error */
+ domain_error:
errno = EDOM;
return zero/zero;
}