This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Platform may have only one of lgamma/tgamma.
[perl5.git] / ext / POSIX / POSIX.xs
index 0dcf43e..452f766 100644 (file)
@@ -648,6 +648,14 @@ static NV my_fdim(NV x, NV y)
 #  define c99_fdim my_fdim
 #endif
 
+#ifndef c99_fma
+static NV my_fma(NV x, NV y, NV z)
+{
+  return (x * y) + z;
+}
+#  define c99_fma my_fma
+#endif
+
 #ifndef c99_fmax
 static NV my_fmax(NV x, NV y)
 {
@@ -728,16 +736,21 @@ static IV my_ilogb(NV x)
  * nor these) do NOT set the global signgam variable.  This is not
  * necessarily a bad thing. */
 
-/* Note that tgamma() and lgamma() depend on each other. */
-#if !defined(c99_tgamma) || !defined(c99_lgamma)
+/* Note that tgamma() and lgamma() implementations depend on each other. */
+
+#ifndef c99_tgamma
 static NV my_tgamma(NV x);
+#  define c99_tgamma my_tgamma
+#endif
+#ifndef c99_lgamma
 static NV my_lgamma(NV x);
+#  define c99_lgamma my_lgamma
 #endif
 
-#if !defined(c99_tgamma) || !defined(c99_lgamma)
+#ifndef HAS_TGAMMA
 static NV my_tgamma(NV x)
 {
-  const NV gamma = 0.577215664901532860606512090; // Euler's gamma constant.
+  const NV gamma = 0.577215664901532860606512090; /* Euler's gamma constant. */
   if (Perl_isnan(x) || x < 0.0)
     return NV_NAN;
   if (x == 0.0 || x == NV_INF)
@@ -747,7 +760,7 @@ static NV my_tgamma(NV x)
    * (0, 0.001), [0.001, 12), and (12, infinity) */
 
   /* First interval: (0, 0.001)
-   * For small values, 1/tgamma(x) has power series x + gamma x^2  ,
+   * For small values, 1/tgamma(x) has power series x + gamma x^2,
    * so in this range, 1/tgamma(x) = x + gamma x^2 with error on the order of x^3.
    * The relative error over this interval is less than 6e-7. */
   if (x < 0.001)
@@ -818,14 +831,11 @@ static NV my_tgamma(NV x)
     return NV_INF;
   }
 
-  return Perl_exp(my_lgamma(x));
+  return Perl_exp(c99_lgamma(x));
 }
-#  ifndef c99_tgamma
-#    define c99_tgamma my_tgamma
-#  endif
 #endif
 
-#if !defined(c99_lgamma) || !defined(c99_tgamma)
+#ifndef HAS_LGAMMA
 static NV my_lgamma(NV x)
 {
   if (Perl_isnan(x))
@@ -835,11 +845,11 @@ static NV my_lgamma(NV x)
   if (x == 1.0 || x == 2.0)
     return 0;
   if (x < 12.0)
-    return Perl_log(PERL_ABS(my_tgamma(x)));
-  // Abramowitz and Stegun 6.1.41
-  // Asymptotic series should be good to at least 11 or 12 figures
-  // For error analysis, see Whittiker and Watson
-  // A Course in Modern Analysis (1927), page 252
+    return Perl_log(PERL_ABS(c99_tgamma(x)));
+  /* Abramowitz and Stegun 6.1.41
+   * Asymptotic series should be good to at least 11 or 12 figures
+   * For error analysis, see Whittiker and Watson
+   * A Course in Modern Analysis (1927), page 252 */
   {
     static const NV c[8] = {
       1.0/12.0,
@@ -865,9 +875,6 @@ static NV my_lgamma(NV x)
     return (x - 0.5) * Perl_log(x) - x + half_log_of_two_pi + series;
   }
 }
-#  ifndef c99_lgamma
-#    define c99_lgamma my_lgamma
-#  endif
 #endif
 
 #ifndef c99_log1p
@@ -2606,9 +2613,6 @@ fma(x,y,z)
     CODE:
 #ifdef c99_fma
        RETVAL = c99_fma(x, y, z);
-#else
-       RETVAL = NV_NAN;
-       not_here("fma");
 #endif
     OUTPUT:
        RETVAL