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
