In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/9d233e1229b9d4643a30bb6859b534d2052d00cd?hp=c0cd65b2410a7d7f64d2d3336de4f12861b430b2>

- Log -----------------------------------------------------------------
commit 9d233e1229b9d4643a30bb6859b534d2052d00cd
Author: Jarkko Hietaniemi <[email protected]>
Date:   Sun Aug 31 23:07:58 2014 -0400

    POSIX math: First cut at C99 math docs.
    
    Undoubtedly stuff missing and incorrect.  And typod.

M       ext/POSIX/POSIX.xs
M       ext/POSIX/lib/POSIX.pod

commit 93ddb8563c00a50b485d75912154ec385ac6882b
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 13:25:42 2014 -0400

    POSIX math: Perl_ldexp, not Perl_ldexpl.

M       ext/POSIX/POSIX.xs

commit 3f8e6f9372054f6e24e02091f356931a5393d6c2
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 13:03:53 2014 -0400

    POSIX math: define the fpclassify returns always if needed.
    
    (Even without HAS_FPCLASSIFY.)

M       ext/POSIX/POSIX.xs

commit 78a0541adf3d472feb6fc3b08fdcb97a9e5538fe
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 09:29:30 2014 -0400

    POSIX math: Initialize RETVAL to NV_NAN/-1.

M       ext/POSIX/POSIX.xs

commit baeba133ac9cc47abf30483d9e003d8e17432e20
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 08:51:39 2014 -0400

    POSIX math: M_LN10 was missing.

M       ext/POSIX/Makefile.PL
M       ext/POSIX/lib/POSIX.pm
M       ext/POSIX/t/export.t

commit 53e66ff6a7ac563f0fe0fbdb0954b20d93438b73
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 13:15:31 2014 -0400

    HP-UX: missing C99 math.

M       ext/POSIX/POSIX.xs

commit c782ab84aeb2abcd3975b09cc4909b8488c3939e
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 12:13:03 2014 -0400

    HP-UX: 10.X doesn't really have isfinite().

M       hints/hpux.sh

commit 636a970bf2930ff403635f62b602c6750cb49207
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 11:30:57 2014 -0400

    HP-UX: 10.20 math functions don't generate infinities.
    
    So skip the tests that attempt creating such.

M       t/op/infnan.t

commit 255abbe733f8e30242cc9a833cc29fec297533e4
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 12:17:02 2014 -0400

    Use Perl_isfinite() to guard the frexpl.
    
    Also, print out the deadly nv.

M       pod/perldiag.pod
M       sv.c

commit efcbf317d0eb22b93b2044fd752161f57b55dd65
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 10:06:10 2014 -0400

    Perl_isinf and Perl_isfinite fallbacks.
    
    (We have so many fallbacks that some of them probably never deploy.)

M       perl.h

commit a985cadd390dc83e2be80ce22961ff6da5e6feb5
Author: Jarkko Hietaniemi <[email protected]>
Date:   Mon Sep 1 09:55:23 2014 -0400

    Do not use HUGE_VAL/VALL for NV_INF.
    
    Because some platforms (like HP-UX 10.*) have HUGE_VAL as DBL_MAX,
    which, while large, is not quite the infinity.  So have infinity
    own our very own.
    
    Similarly for NV_NAN.

M       embedvar.h
M       perl.h
M       perlapi.h
M       perlvars.h
-----------------------------------------------------------------------

Summary of changes:
 embedvar.h              |   4 +
 ext/POSIX/Makefile.PL   |   2 +-
 ext/POSIX/POSIX.xs      |  62 +++++++++---
 ext/POSIX/lib/POSIX.pm  |   2 +-
 ext/POSIX/lib/POSIX.pod | 262 ++++++++++++++++++++++++++++++++++++++++++++++++
 ext/POSIX/t/export.t    |   2 +-
 hints/hpux.sh           |   7 ++
 perl.h                  |  23 +++--
 perlapi.h               |   4 +
 perlvars.h              |  13 +++
 pod/perldiag.pod        |   2 +-
 sv.c                    |   8 +-
 t/op/infnan.t           |  16 ++-
 13 files changed, 371 insertions(+), 36 deletions(-)

diff --git a/embedvar.h b/embedvar.h
index 766880c..0ae37a1 100644
--- a/embedvar.h
+++ b/embedvar.h
@@ -375,6 +375,8 @@
 #define PL_Ghash_seed_set      (my_vars->Ghash_seed_set)
 #define PL_hints_mutex         (my_vars->Ghints_mutex)
 #define PL_Ghints_mutex                (my_vars->Ghints_mutex)
+#define PL_infinity            (my_vars->Ginfinity)
+#define PL_Ginfinity           (my_vars->Ginfinity)
 #define PL_keyword_plugin      (my_vars->Gkeyword_plugin)
 #define PL_Gkeyword_plugin     (my_vars->Gkeyword_plugin)
 #define PL_malloc_mutex                (my_vars->Gmalloc_mutex)
@@ -385,6 +387,8 @@
 #define PL_Gmy_ctx_mutex       (my_vars->Gmy_ctx_mutex)
 #define PL_my_cxt_index                (my_vars->Gmy_cxt_index)
 #define PL_Gmy_cxt_index       (my_vars->Gmy_cxt_index)
+#define PL_nan                 (my_vars->Gnan)
+#define PL_Gnan                        (my_vars->Gnan)
 #define PL_op_mutex            (my_vars->Gop_mutex)
 #define PL_Gop_mutex           (my_vars->Gop_mutex)
 #define PL_op_seq              (my_vars->Gop_seq)
diff --git a/ext/POSIX/Makefile.PL b/ext/POSIX/Makefile.PL
index b8f559a..02a3332 100644
--- a/ext/POSIX/Makefile.PL
+++ b/ext/POSIX/Makefile.PL
@@ -112,7 +112,7 @@ push @names, {name=>$_, type=>"NV"}
 
 push @names, {name=>$_, type=>"NV"}
   foreach (qw(FP_ILOGB0 FP_ILOGBNAN FP_INFINITE FP_NAN FP_NORMAL
-              FP_SUBNORMAL FP_ZERO M_1_PI M_2_PI M_2_SQRTPI M_E M_LN2
+              FP_SUBNORMAL FP_ZERO M_1_PI M_2_PI M_2_SQRTPI M_E M_LN10 M_LN2
               M_LOG10E M_LOG2E M_PI M_PI_2 M_PI_4 M_SQRT1_2 M_SQRT2));
 
 push @names, {name=>$_, type=>"IV"}
diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs
index c250831..5073733 100644
--- a/ext/POSIX/POSIX.xs
+++ b/ext/POSIX/POSIX.xs
@@ -114,7 +114,7 @@
 #endif
 
 /* We will have an emulation. */
-#if !defined(HAS_FPCLASSIFY) && !defined(FP_INFINITE)
+#ifndef FP_INFINITE
 #  define FP_INFINITE  0
 #  define FP_NAN       1
 #  define FP_NORMAL    2
@@ -131,24 +131,30 @@
 
    atan2 cos exp log pow sin sqrt
 
-  * Berkeley/SVID extensions:
+ * C99 math.h added:
 
-    j0 j1 jn y0 y1 yn
+   acosh asinh atanh cbrt copysign erf erfc exp2 expm1 fdim fma fmax
+   fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal isinf
+   isless islessequal islessgreater isnan isnormal isunordered lgamma
+   log1p log2 logb lrint nan nearbyint nextafter nexttoward remainder
+   remquo rint round scalbn signbit tgamma trunc
 
- * C99 math.h added:
+  * Berkeley/SVID extensions:
 
-   acosh asinh atanh cbrt copysign cosh erf erfc exp2 expm1 fdim fma
-   fmax fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal
-   isinf isless islessequal islessgreater isnan isnormal isunordered
-   lgamma log1p log2 logb lrint nan nearbyint nextafter nexttoward remainder
-   remquo rint round scalbn signbit sinh tanh tgamma trunc
+    j0 j1 jn y0 y1 yn
 
   * Configure already (5.21.0) scans for:
 
     fpclassify isfinite isinf isnan ilogb*l* signbit
 
+  * For floating-point round mode (which matters for e.g. lrint and rint)
+
+    fegetround fesetround
+
 */
 
+/* XXX Constant FP_FAST_FMA (if true, FMA is faster) */
+
 /* XXX Add ldiv(), lldiv()?  It's C99, but from stdlib.h, not math.h  */
 
 /* XXX Beware old gamma() -- one cannot know whether that is the
@@ -271,15 +277,31 @@
 /* If on legacy platforms, and not using gcc, some C99 math interfaces
  * might be missing, turn them off so that the emulations hopefully
  * kick in.  This is admittedly nasty, and fragile, but the alternative
- * is to have Configure scans for all the 40+ interfaces. */
+ * is to have Configure scans for all the 40+ interfaces.
+ *
+ * In other words: if you have an incomplete (or broken) C99 math interface,
+ * #undef the c99_foo here, and let the emulations kick in. */
+
 #ifndef __GNUC__
 
 /* HP-UX on PA-RISC is missing certain C99 math functions,
  * but on IA64 (Integrity) these do exist. */
 #  if defined(__hpux) && defined(__hppa)
+#    undef c99_exp2
+#    undef c99_fdim
 #    undef c99_fma
+#    undef c99_fmax
+#    undef c99_fmin
+#    undef c99_fpclassify
+#    undef c99_lrint
+#    undef c99_nan
+#    undef c99_nearbyint
 #    undef c99_nexttoward
+#    undef c99_remquo
+#    undef c99_round
+#    undef c99_scalbn
 #    undef c99_tgamma
+#    undef c99_trunc
 #  endif
 
 #  if defined(__irix__)
@@ -494,16 +516,15 @@ static NV my_fmin(NV x, NV y)
 #  define c99_fmin my_fmin
 #endif
 
-#if !(defined(HAS_FPCLASSIFY) && defined(FP_INFINITE))
 static NV my_fpclassify(NV x)
 {
-#if defined(HAS_FPCLASSIFY) && defined(FP_PLUS_INF)
+#if defined(HAS_FPCLASSIFY) && defined(FP_PLUS_INF) /* E.g. HP-UX */
   switch (Perl_fp_class(x)) {
   case FP_PLUS_INF:    case FP_MINUS_INF:    return FP_INFINITE;
   case FP_SNAN:        case FP_QNAN:         return FP_NAN;
   case FP_PLUS_NORM:   case FP_MINUS_NORM:   return FP_NORMAL;
   case FP_PLUS_DENORM: case FP_MINUS_DENORM: return FP_SUBNORMAL;
-  case FP_PLUS_ZERO:   case FP_MINUS_PZERO:  return FP_ZERO;
+  case FP_PLUS_ZERO:   case FP_MINUS_ZERO:   return FP_ZERO;
   default: return -1;
   }
 #  define c99_fpclassify my_fpclassify
@@ -563,7 +584,6 @@ static NV my_fpclassify(NV x)
   return -1;
 #endif
 }
-#endif
 
 #ifndef c99_hypot
 static NV my_hypot(NV x, NV y)
@@ -684,7 +704,7 @@ static NV my_round(NV x)
 #endif
 
 #ifndef c99_scalbn
-#   if defined(Perl_ldexpl) && FLT_RADIX == 2
+#   if defined(Perl_ldexp) && FLT_RADIX == 2
 static NV my_scalbn(NV x)
 {
   return Perl_ldexp(x, y);
@@ -1791,6 +1811,7 @@ acos(x)
        y0 = 29
        y1 = 30
     CODE:
+       RETVAL = NV_NAN;
        switch (ix) {
        case 0:
            RETVAL = acos(x); /* C89 math */
@@ -1978,8 +1999,10 @@ acos(x)
 IV
 fegetround()
     CODE:
+#ifdef HAS_FEGETROUND
        RETVAL = my_fegetround();
-#ifndef HAS_FEGETROUND
+#else
+       RETVAL = -1;
        not_here("fegetround");
 #endif
     OUTPUT:
@@ -1992,6 +2015,7 @@ fesetround(x)
 #ifdef HAS_FEGETROUND /* canary for fesetround */
        RETVAL = fesetround(x);
 #else
+       RETVAL = -1;
        not_here("fesetround");
 #endif
     OUTPUT:
@@ -2009,6 +2033,7 @@ fpclassify(x)
        lrint = 6
         signbit = 7
     CODE:
+       RETVAL = -1;
        switch (ix) {
        case 0:
 #ifdef c99_fpclassify
@@ -2077,6 +2102,7 @@ copysign(x,y)
        nexttoward = 13
        remainder = 14
     CODE:
+       RETVAL = NV_NAN;
        switch (ix) {
        case 0:
 #ifdef c99_copysign
@@ -2228,6 +2254,7 @@ scalbn(x,y)
 #ifdef c99_scalbn
        RETVAL = c99_scalbn(x, y);
 #else
+       RETVAL = NV_NAN;
        not_here("scalbn");
 #endif
     OUTPUT:
@@ -2242,6 +2269,7 @@ fma(x,y,z)
 #ifdef c99_fma
        RETVAL = c99_fma(x, y, z);
 #else
+       RETVAL = NV_NAN;
        not_here("fma");
 #endif
     OUTPUT:
@@ -2254,6 +2282,7 @@ nan(s = 0)
 #ifdef c99_nan
        RETVAL = c99_nan(s);
 #else
+       RETVAL = NV_NAN;
        not_here("nan");
 #endif
     OUTPUT:
@@ -2266,6 +2295,7 @@ jn(x,y)
     ALIAS:
        yn = 1
     CODE:
+       RETVAL = NV_NAN;
         switch (ix) {
        case 0:
 #ifdef bessel_jn
diff --git a/ext/POSIX/lib/POSIX.pm b/ext/POSIX/lib/POSIX.pm
index 121a936..0b236d2 100644
--- a/ext/POSIX/lib/POSIX.pm
+++ b/ext/POSIX/lib/POSIX.pm
@@ -301,7 +301,7 @@ our %EXPORT_TAGS = (
 
     math_h => [qw(FP_ILOGB0 FP_ILOGBNAN FP_INFINITE FP_NAN FP_NORMAL
                   FP_SUBNORMAL FP_ZERO HUGE_VAL INFINITY Inf M_1_PI
-                  M_2_PI M_2_SQRTPI M_E M_LN2 M_LOG10E M_LOG2E M_PI
+                  M_2_PI M_2_SQRTPI M_E M_LN10 M_LN2 M_LOG10E M_LOG2E M_PI
                   M_PI_2 M_PI_4 M_SQRT1_2 M_SQRT2 NAN NaN acos acosh
                   asin asinh atan atanh cbrt ceil copysign cosh erf
                   erfc exp2 expm1 fabs fdim floor fma fmax fmin fmod
diff --git a/ext/POSIX/lib/POSIX.pod b/ext/POSIX/lib/POSIX.pod
index 73c500b..945cfaf 100644
--- a/ext/POSIX/lib/POSIX.pod
+++ b/ext/POSIX/lib/POSIX.pod
@@ -41,6 +41,32 @@ and other miscellaneous objects.  The remaining sections 
list various
 constants and macros in an organization which roughly follows IEEE Std
 1003.1b-1993.
 
+=head1 C99 "math" interfaces
+
+Mathematic functions and constants from the C99 standard are available
+on many platforms.  In the below functions list they are marked [C99].
+
+The mathematical constants include:
+
+  M_SQRT2    # the square root of two
+  M_E        # the Euler's (or Napier's) constant
+  M_PI       # the Pi
+
+and other related/similar ones
+
+  M_SQRT1_2  # sqrt(1/2)
+  M_LN10 M_LN2 M_LOG10E M_LOG2E
+  M_1_PI M_2_PI M_2_SQRTPI M_PI_2 M_PI_4  # 1/Pi, ..., Pi/4
+
+and the
+
+  INFINITY
+  NAN
+
+The last two are also available as just Inf and NaN.
+
+The Bessel functions (j0, j1, jn, y0, y1, yn) are also available.
+
 =head1 CAVEATS
 
 A few functions are not implemented because they are C specific.  If you
@@ -102,6 +128,12 @@ I<race condition>.
 This is identical to the C function C<acos()>, returning
 the arcus cosine of its numerical argument.  See also L<Math::Trig>.
 
+=item C<acosh>
+
+This is identical to the C function C<acos()>, returning the
+hyperbolic arcus cosine of its numerical argument [C99].  See also
+L<Math::Trig>.
+
 =item C<alarm>
 
 This is identical to Perl's builtin C<alarm()> function,
@@ -128,6 +160,12 @@ The C<$mon> is zero-based: January equals C<0>.  The 
C<$year> is
 This is identical to the C function C<asin()>, returning
 the arcus sine of its numerical argument.  See also L<Math::Trig>.
 
+=item C<asinh>
+
+This is identical to the C function C<asin()>, returning the
+hyperbolic arcus sine of its numerical argument [C99].  See also
+L<Math::Trig>.
+
 =item C<assert>
 
 Unimplemented, but you can use L<perlfunc/die> and the L<Carp> module
@@ -138,6 +176,12 @@ to achieve similar things.
 This is identical to the C function C<atan()>, returning the
 arcus tangent of its numerical argument.  See also L<Math::Trig>.
 
+=item C<atanh>
+
+This is identical to the C function C<atan()>, returning the
+hyperbolic arcus tangent of its numerical argument [C99].  See also
+L<Math::Trig>.
+
 =item C<atan2>
 
 This is identical to Perl's builtin C<atan2()> function, returning
@@ -174,6 +218,10 @@ see L<Search::Dict>.
 
 C<calloc()> is C-specific.  Perl does memory management transparently.
 
+=item C<cbrt>
+
+The cube root [C99].
+
 =item C<ceil>
 
 This is identical to the C function C<ceil()>, returning the smallest
@@ -232,6 +280,12 @@ See also L<Math::Trig>.
 This is identical to the C function C<cosh()>, for returning
 the hyperbolic cosine of its numeric argument.  See also L<Math::Trig>.
 
+=item C<copysign>
+
+Returns the x but with the sign of y [C99].
+
+See also L</signbit>.
+
 =item C<creat>
 
 Create a new file.  This returns a file descriptor like the ones returned by
@@ -290,6 +344,14 @@ C<POSIX::open>.
 
 Returns C<undef> on failure.
 
+=item C<erf>
+
+The error function [C99].
+
+=item C<erfc>
+
+The complementary error function [C99].
+
 =item C<errno>
 
 Returns the value of errno.
@@ -333,6 +395,12 @@ This is identical to Perl's builtin C<exp()> function for
 returning the exponent (I<e>-based) of the numerical argument,
 see L<perlfunc/exp>.
 
+=item C<expm1>
+
+Equivalent to C<exp(x) - 1>, but more precise for small argument values [C99].
+
+See also L</log1p>.
+
 =item C<fabs>
 
 This is identical to Perl's builtin C<abs()> function for returning
@@ -386,6 +454,35 @@ Use method C<IO::Handle::fileno()> instead, or see 
L<perlfunc/fileno>.
 This is identical to the C function C<floor()>, returning the largest
 integer value less than or equal to the numerical argument.
 
+=item C<fdim>
+
+"Positive difference", x - y if x > y, zero otherwise [C99].
+
+=item C<fegetround>
+
+Returns the current floating point rounding mode, one of
+
+  FE_TONEAREST FE_TOWARDZERO FE_UPWARD FE_UPWARD
+
+FE_TONEAREST is like L</round>, FE_TOWARDZERO is like L</trunc> [C99].
+
+=item C<fesetround>
+
+Sets the floating point rounding mode, see L</fegetround>.
+
+=item C<fma>
+
+"Fused multiply-add", x * y + z, possibly faster (and less lossy)
+than the explicit two operations [C99].
+
+=item C<fmax>
+
+Maximum of x and y, except when either is NaN, returns the other [C99].
+
+=item C<fmin>
+
+Minimum of x and y, except when either is NaN, returns the other [C99].
+
 =item C<fmod>
 
 This is identical to the C function C<fmod()>.
@@ -419,6 +516,14 @@ pathname on the filesystem which holds F</var/foo>.
 
 Returns C<undef> on failure.
 
+=item C<fpclassify>
+
+Returns one of
+
+  FP_NORMAL FP_ZERO FP_SUBNORMAL FP_INFINITE FP_NAN
+
+telling the class of the argument [C99].
+
 =item C<fprintf>
 
 C<fprintf()> is C-specific, see L<perlfunc/printf> instead.
@@ -587,6 +692,17 @@ This is identical to Perl's builtin C<gmtime()> function 
for
 converting seconds since the epoch to a date in Greenwich Mean Time,
 see L<perlfunc/gmtime>.
 
+=item C<hypot>
+
+Equivalent to sqrt(x * x + y * y) except more stable on very large
+or very small arguments [C99].
+
+=item C<ilogb>
+
+Integer binary logarithm [C99], e.g. ilogb(30) is 4.
+
+Identical to L</logb>.
+
 =item C<isalnum>
 
 Deprecated function whose use raises a warning, and which is slated to
@@ -662,6 +778,13 @@ corresponding C function returns C<TRUE> for every byte in 
the string.
 You may want to use the C<L<E<sol>\dE<sol>|perlrecharclass/Digits>>
 construct instead.
 
+=item C<isfinite>
+
+Returns true if the argument is a finite number (that is, not an
+infinity, or the not-a-number) [C99].
+
+See also L</isinf>, L</isnan>, and L</fpclassify>.
+
 =item C<isgraph>
 
 Deprecated function whose use raises a warning, and which is slated to
@@ -678,6 +801,19 @@ modifier is in effect?>).
 The function returns C<TRUE> if the input string is empty, or if the
 corresponding C function returns C<TRUE> for every byte in the string.
 
+=item C<isgreater>
+
+(Also C<isgreaterequal>, C<isless>, C<islessequal>, C<islessgreater>,
+C<isunordered>)
+
+Floating point comparisons which handle the NaN [C99].
+
+=item C<isinf>
+
+Returns true if the argument is an infinity (positive or negative) [C99].
+
+See also L</isnan>, L</isfinite>, and L</fpclassify>.
+
 =item C<islower>
 
 Deprecated function whose use raises a warning, and which is slated to
@@ -696,6 +832,25 @@ corresponding C function returns C<TRUE> for every byte in 
the string.
 
 Do B<not> use C</[a-z]/> unless you don't care about the current locale.
 
+=item C<isnan>
+
+Returns true if the argument is NaN (not-a-number) [C99].
+
+Note that you cannot test for "NaN-ness" with
+
+   $x == $x
+
+since the NaN is not equivalent to anything, B<including itself>.
+
+See also L</isinf>, and L</fpclassify>.
+
+=item C<isnormal>
+
+Returns true if the argument is normal (that is, not a subnormal/denormal,
+and not an infinity, or a not-a-number) [C99].
+
+See also L</isfinite>, and L</fpclassify>.
+
 =item C<isprint>
 
 Deprecated function whose use raises a warning, and which is slated to
@@ -781,6 +936,12 @@ modifier is in effect?>).
 The function returns C<TRUE> if the input string is empty, or if the
 corresponding C function returns C<TRUE> for every byte in the string.
 
+=item C<j0>
+
+(Also C<j1>, C<jn>, C<y0>, C<y1>, C<yn>)
+
+The Bessel function of the first kind of the order zero.
+
 =item C<kill>
 
 This is identical to Perl's builtin C<kill()> function for sending
@@ -811,6 +972,29 @@ for multiplying floating point numbers with powers of two.
 (For computing dividends of long integers.)
 C<ldiv()> is C-specific, use C</> and C<int()> instead.
 
+=item C<lgamma>
+
+The logarithm of the Gamma function [C99].
+
+See also L</tgamma>.
+
+=item C<log1p>
+
+Equivalent to log(1 + x), but more stable results for small argument
+values [C99].
+
+=item C<log2>
+
+Logarithm base two [C99].
+
+See also L</expm1>.
+
+=item C<logb>
+
+Integer binary logarithm [C99].
+
+Identical to L</ilogb>.
+
 =item C<link>
 
 This is identical to Perl's builtin C<link()> function
@@ -895,6 +1079,14 @@ those obtained by calling C<POSIX::open>.
 
 Returns C<undef> on failure.
 
+=item C<lrint>
+
+Depending on the floating point rounding mode, rounds the argument
+either toward nearest, toward zero, downward (toward negative infinity),
+or upward (toward positive infinity) [C99].
+
+For the rounding mode, see L</fegetround> and L</fesetround>.
+
 =item C<malloc>
 
 C<malloc()> is C-specific.  Perl does memory management transparently.
@@ -984,6 +1176,29 @@ Return the integral and fractional parts of a 
floating-point number.
 
        ($fractional, $integral) = POSIX::modf( 3.14 );
 
+=item C<nan>
+
+Returns not-a-number [C99].
+
+=item C<nearbyint>
+
+Returns the nearest integer to the argument, according to the current
+rounding mode (see L</fegetround>) [C99].
+
+=item C<nextafter>
+
+Returns the next representable floating point number after x in the
+direction of y [C99].
+
+Like L</nexttoward>, but potentially less accurate.
+
+=item C<nexttoward>
+
+Returns the next representable floating point number after x in the
+direction of y [C99].
+
+Like L</nextafter>, but potentially more accurate.
+
 =item C<nice>
 
 This is similar to the C function C<nice()>, for changing
@@ -1133,11 +1348,26 @@ for reading directory entries, see L<perlfunc/readdir>.
 
 C<realloc()> is C-specific.  Perl does memory management transparently.
 
+=item C<remainder>
+
+Given x and y, returns the value x - n*y, where n is the integer
+closest to x/y. [C99]
+
+See also L</remquo>.
+
 =item C<remove>
 
 This is identical to Perl's builtin C<unlink()> function
 for removing files, see L<perlfunc/unlink>.
 
+=item C<remquo>
+
+Like L</remainder> but also returns the low-order bits of the quotient (n)
+[C99]
+
+(This is quite esoteric interface, mainly used to implement numerical
+algorithms.)
+
 =item C<rename>
 
 This is identical to Perl's builtin C<rename()> function
@@ -1152,11 +1382,27 @@ Seeks to the beginning of the file.
 This is identical to Perl's builtin C<rewinddir()> function for
 rewinding directory entry streams, see L<perlfunc/rewinddir>.
 
+=item C<rint>
+
+Identical to L</lrint>.
+
 =item C<rmdir>
 
 This is identical to Perl's builtin C<rmdir()> function
 for removing (empty) directories, see L<perlfunc/rmdir>.
 
+=item C<round>
+
+Returns the integer nearest to the argument [C99].
+
+See also L</ceil>, L</floor>, L</trunc>.
+
+=item C<scalbn>
+
+Returns x * 2**y [C99].
+
+See also L</frexp> and L</ldexp>.
+
 =item C<scanf>
 
 C<scanf()> is C-specific, use E<lt>E<gt> and regular expressions instead,
@@ -1285,6 +1531,10 @@ C<sigaction> and possibly also C<siginfo> documentation.
 
 C<siglongjmp()> is C-specific: use L<perlfunc/die> instead.
 
+=item C<signbit>
+
+Returns zero for positive arguments, non-zero for negative arguments [C99].
+
 =item C<sigpending>
 
 Examine signals that are blocked and pending.  This uses C<POSIX::SigSet>
@@ -1635,6 +1885,12 @@ terminal.
 
 Returns C<undef> on failure.
 
+=item C<tgamma>
+
+The Gamma function [C99].
+
+See also L</lgamma>.
+
 =item C<time>
 
 This is identical to Perl's builtin C<time()> function
@@ -1682,6 +1938,12 @@ character or to a whole string.  Consider using the 
C<uc()> function,
 see L<perlfunc/uc>, or the equivalent C<\U> operator inside doublequotish
 strings.
 
+=item C<trunc>
+
+Returns the integer toward zero from the argument [C99].
+
+See also L</ceil>, L</floor>, and L</round>.
+
 =item C<ttyname>
 
 This is identical to the C function C<ttyname()> for returning the
diff --git a/ext/POSIX/t/export.t b/ext/POSIX/t/export.t
index 24a318f..caa7f2b 100644
--- a/ext/POSIX/t/export.t
+++ b/ext/POSIX/t/export.t
@@ -51,7 +51,7 @@ my %expect = (
                  LDBL_MIN_10_EXP LDBL_MIN_EXP LINK_MAX LONG_MAX
                  LONG_MIN L_ctermid L_cuserid L_tmpname MAX_CANON
                  MAX_INPUT MB_CUR_MAX MB_LEN_MAX M_1_PI M_2_PI M_2_SQRTPI
-                 M_E M_LN2 M_LOG10E M_LOG2E M_PI M_PI_2 M_PI_4
+                 M_E M_LN10 M_LN2 M_LOG10E M_LOG2E M_PI M_PI_2 M_PI_4
                  M_SQRT1_2 M_SQRT2 NAME_MAX NAN NCCS NDEBUG
                  NGROUPS_MAX NOFLSH NULL NaN OPEN_MAX OPOST O_ACCMODE
                  O_APPEND O_CREAT O_EXCL O_NOCTTY O_NONBLOCK O_RDONLY
diff --git a/hints/hpux.sh b/hints/hpux.sh
index 6ee7cdf..39150be 100644
--- a/hints/hpux.sh
+++ b/hints/hpux.sh
@@ -773,3 +773,10 @@ case "`grep 'double strtold.const' /usr/include/stdlib.h`" 
in
 *) echo "Looks like your strtold() is non-standard..." >&4
    d_strtold=undef ;;
 esac
+
+# In pre-11 HP-UXes there really isn't isfinite(), despite what
+# Configure might think. (There is finite(), though.)
+case "`grep 'isfinite' /usr/include/math.h`" in
+*"isfinite"*) ;;
+*) d_isfinite=undef ;;
+esac
diff --git a/perl.h b/perl.h
index 8ea9a2a..36ecb50 100644
--- a/perl.h
+++ b/perl.h
@@ -1932,6 +1932,8 @@ EXTERN_C long double modfl(long double, long double *);
 #   ifndef Perl_isinf
 #       if defined(HAS_ISINFL) && !(defined(isinf) && HAS_C99)
 #           define Perl_isinf(x) isinfl(x)
+#       elif defined(LDBL_MAX)
+#           define Perl_isinf(x) ((x) > LDBL_MAX || (x) < -LDBL_MAX)
 #       endif
 #   endif
 #   if !defined(Perl_isfinite) && !(defined(isfinite) && HAS_C99)
@@ -1939,6 +1941,8 @@ EXTERN_C long double modfl(long double, long double *);
 #       define Perl_isfinite(x) isfinitel(x)
 #     elif defined(HAS_FINITEL)
 #       define Perl_isfinite(x) finitel(x)
+#     elif defined(LDBL_MAX)
+#       define Perl_isfinite(x) ((x) <= LDBL_MAX && (x) >= -LDBL_MAX)
 #     endif
 #   endif
 #else
@@ -1996,6 +2000,8 @@ EXTERN_C long double modfl(long double, long double *);
 #   ifndef Perl_isinf
 #       if defined(HAS_ISINF)
 #           define Perl_isinf(x) isinf(x)
+#       elif defined(DBL_MAX)
+#           define Perl_isinf(x) ((x) > DBL_MAX || (x) < -DBL_MAX)
 #       endif
 #   endif
 #   ifndef Perl_isfinite
@@ -2003,6 +2009,8 @@ EXTERN_C long double modfl(long double, long double *);
 #       define Perl_isfinite(x) isfinite(x)
 #     elif defined(HAS_FINITE)
 #       define Perl_isfinite(x) finite(x)
+#     elif defined(DBL_MAX)
+#       define Perl_isfinite(x) ((x) <= DBL_MAX && (x) >= -DBL_MAX)
 #     endif
 #   endif
 #endif
@@ -4106,11 +4114,8 @@ END_EXTERN_C
 #if !defined(NV_INF) && defined(INF)
 #  define NV_INF (NV)INF
 #endif
-#if !defined(NV_INF) && defined(USE_LONG_DOUBLE) && defined(HUGE_VALL)
-#  define NV_INF (NV)HUGE_VALL
-#endif
-#if !defined(NV_INF) && defined(HUGE_VAL)
-#  define NV_INF (NV)HUGE_VAL
+#if !defined(NV_INF)
+#  define NV_INF (NV)PL_infinity
 #endif
 
 #if !defined(NV_NAN) && defined(USE_LONG_DOUBLE)
@@ -4136,14 +4141,14 @@ END_EXTERN_C
 #if !defined(NV_NAN) && defined(QNAN)
 #  define NV_NAN (NV)QNAN
 #endif
-#if !defined(NV_NAN) && defined(SNAN)
-#  define NV_NAN (NV)SNAN
-#endif
 #if !defined(NV_NAN) && defined(NAN)
 #  define NV_NAN (NV)NAN
 #endif
+#if !defined(NV_NAN) && defined(SNAN)
+#  define NV_NAN (NV)SNAN
+#endif
 #if !defined(NV_NAN) && defined(NV_INF)
-#  define NV_NAN (NV_INF-NV_INF)
+#  define NV_NAN PL_nan
 #endif
 
 #ifndef __cplusplus
diff --git a/perlapi.h b/perlapi.h
index 910f789..da48b53 100644
--- a/perlapi.h
+++ b/perlapi.h
@@ -121,6 +121,8 @@ END_EXTERN_C
 #define PL_hash_seed_set       (*Perl_Ghash_seed_set_ptr(NULL))
 #undef  PL_hints_mutex
 #define PL_hints_mutex         (*Perl_Ghints_mutex_ptr(NULL))
+#undef  PL_infinity
+#define PL_infinity            (*Perl_Ginfinity_ptr(NULL))
 #undef  PL_keyword_plugin
 #define PL_keyword_plugin      (*Perl_Gkeyword_plugin_ptr(NULL))
 #undef  PL_malloc_mutex
@@ -131,6 +133,8 @@ END_EXTERN_C
 #define PL_my_ctx_mutex                (*Perl_Gmy_ctx_mutex_ptr(NULL))
 #undef  PL_my_cxt_index
 #define PL_my_cxt_index                (*Perl_Gmy_cxt_index_ptr(NULL))
+#undef  PL_nan
+#define PL_nan                 (*Perl_Gnan_ptr(NULL))
 #undef  PL_op_mutex
 #define PL_op_mutex            (*Perl_Gop_mutex_ptr(NULL))
 #undef  PL_op_seq
diff --git a/perlvars.h b/perlvars.h
index 7bafa40..40f5072 100644
--- a/perlvars.h
+++ b/perlvars.h
@@ -237,3 +237,16 @@ PERLVAR(G, malloc_mutex, perl_mutex)       /* Mutex for 
malloc */
 
 PERLVARI(G, hash_seed_set, bool, FALSE)        /* perl.c */
 PERLVARA(G, hash_seed, PERL_HASH_SEED_BYTES, unsigned char) /* perl.c and hv.h 
*/
+
+/* The infinity.  Used if no suitable definition is found in <math.h>.
+ * Note: many older places (like HP-UX 10.X) define HUGE_VAL
+ * as DBL_MAX (or LDBL_MAX for long doubles).  Therefore HUGE_VAL
+ * is not a suitable replacement for infinity.
+ *
+ * The division by zero might warn with some compilers. */
+PERLVARIC(G, infinity, NV, (NV)1.0/0.0)
+
+/* The not-a-number.  Used if no suitable definition is found in <math.h>
+ *
+ * The division by zero might warn with some compilers. */
+PERLVARIC(G, nan, NV, (NV)0.0/0.0)
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 910b838..df94c98 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -4002,7 +4002,7 @@ data.
 (P) While attempting folding constants an exception other than an C<eval>
 failure was caught.
 
-=item panic: frexp
+=item panic: frexp: %f
 
 (P) The library function frexp() failed, making printf("%f") impossible.
 
diff --git a/sv.c b/sv.c
index 98836f1..da21d25 100644
--- a/sv.c
+++ b/sv.c
@@ -11711,14 +11711,12 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char 
*const pat, const STRLEN p
 
            need = 0;
            /* frexp() (or frexpl) has some unspecified behaviour for
-             * nan/inf/-inf, so let's avoid calling that on those
-             * three values. nv * 0 will be NaN for NaN, +Inf and -Inf,
-             * and 0 for anything else. */
-           if (isALPHA_FOLD_NE(c, 'e') && (nv * 0) == 0) {
+             * nan/inf/-inf, so let's avoid calling that on non-finites. */
+           if (isALPHA_FOLD_NE(c, 'e') && Perl_isfinite(nv)) {
                 i = PERL_INT_MIN;
                 (void)Perl_frexp(nv, &i);
                 if (i == PERL_INT_MIN)
-                    Perl_die(aTHX_ "panic: frexp");
+                    Perl_die(aTHX_ "panic: frexp: %"NVgf, nv);
                 /* Do not set hexfp earlier since we want to printf
                  * Inf/NaN for Inf/NAN, not their hexfp. */
                 hexfp = isALPHA_FOLD_EQ(c, 'a');
diff --git a/t/op/infnan.t b/t/op/infnan.t
index 3a8be8e..470b6d4 100644
--- a/t/op/infnan.t
+++ b/t/op/infnan.t
@@ -8,6 +8,8 @@ BEGIN {
 
 use strict;
 
+use Config;
+
 my $PInf = "Inf"  + 0;
 my $NInf = "-Inf" + 0;
 my $NaN  = "NaN"  + 0;
@@ -98,7 +100,12 @@ SKIP: {
   is(1/$PInf, 0, "one per +Inf is zero");
   is(1/$NInf, 0, "one per -Inf is zero");
 
-  is(9**9**9, $PInf, "9**9**9 is Inf");
+ SKIP: {
+     if ("$^O $Config{osvers}" eq "hpux 10.20") {
+         skip "pow doesn't generate Inf", 1;
+     }
+     is(9**9**9, $PInf, "9**9**9 is Inf");
+  }
 }
 
 {
@@ -152,7 +159,12 @@ SKIP: {
   is($NaN * 0, $NaN, "NaN times zero is NaN");
   is($NaN * 2, $NaN, "NaN times two is NaN");
 
-  is(sin(9**9**9), $NaN, "sin(9**9**9) is NaN");
+ SKIP: {
+     if ("$^O $Config{osvers}" eq "hpux 10.20") {
+         skip "pow doesn't generate Inf, so sin(Inf) won't happen", 1;
+     }
+     is(sin(9**9**9), $NaN, "sin(9**9**9) is NaN");
+  }
 }
 
 SKIP: {

--
Perl5 Master Repository

Reply via email to