summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTAKAI Kousuke <62541129+t-a-k@users.noreply.github.com>2021-01-19 01:27:37 +0900
committerKarl Williamson <khw@cpan.org>2021-04-17 08:56:47 -0600
commitebdbfbc13a50bac2c7d9a6733bc76d959e1f6a92 (patch)
tree905368fc3660b09691a990629de20b71950c5c9a
parentb56e599f0e1e96c01ab479895467b18a8ffda0a0 (diff)
downloadperl-ebdbfbc13a50bac2c7d9a6733bc76d959e1f6a92.tar.gz
POSIX: Prefer system's NAN/INFINITY for POSIX::NAN and POSIX::INFINITY.
POSIX::NAN and POSIX::INFINITY used to return NV_NAN and NV_INF defined in the perl core respectively, but these might be different from the values defined in the POSIX system header, as these special values might have multiple internal representations. If respective POSIX macro is not defined (eg. on pre-C99 system), they will return NV_NAN/NV_INF, so there should be no degradation.
-rw-r--r--ext/POSIX/Makefile.PL8
-rw-r--r--ext/POSIX/t/math.t29
2 files changed, 30 insertions, 7 deletions
diff --git a/ext/POSIX/Makefile.PL b/ext/POSIX/Makefile.PL
index a124003f23..f673b985b3 100644
--- a/ext/POSIX/Makefile.PL
+++ b/ext/POSIX/Makefile.PL
@@ -95,17 +95,19 @@ END
#else
HUGE_VAL
#endif
- '});
+ '},
+ # POSIX says these are constant expressions, but if these are not available
+ # we might fallback to NV_INF/NV_NAN which may be not constants.
+ {name=>"INFINITY", type=>"NV", not_constant=>1},
+ {name=>"NAN", type=>"NV", not_constant=>1});
if ($Config{d_double_has_inf}) {
push @names,
- {name=>"INFINITY", type=>"NV", value=>"NV_INF", not_constant=>1},
{name=>"Inf", type=>"NV", value=>"NV_INF", not_constant=>1},
}
if ($Config{d_double_has_nan}) {
push @names,
- {name=>"NAN", type=>"NV", value=>"NV_NAN", not_constant=>1},
{name=>"NaN", type=>"NV", value=>"NV_NAN", not_constant=>1};
}
diff --git a/ext/POSIX/t/math.t b/ext/POSIX/t/math.t
index abcdb3d240..f3a162a99b 100644
--- a/ext/POSIX/t/math.t
+++ b/ext/POSIX/t/math.t
@@ -110,17 +110,15 @@ SKIP: {
ok(!isinf(42), "isinf 42");
ok(!isnan(42), "isnan Inf");
SKIP: {
- skip("no inf", 4) unless $Config{d_double_has_inf};
+ skip("no inf", 3) unless $Config{d_double_has_inf};
ok(!isfinite(Inf), "isfinite Inf");
- ok(isinf(INFINITY), "isinf INFINITY");
ok(isinf(Inf), "isinf Inf");
ok(!isnan(Inf), "isnan Inf");
}
SKIP: {
- skip("no nan", 5) unless $Config{d_double_has_nan};
+ skip("no nan", 4) unless $Config{d_double_has_nan};
ok(!isfinite(NaN), "isfinite NaN");
ok(!isinf(NaN), "isinf NaN");
- ok(isnan(NAN), "isnan NAN");
ok(isnan(NaN), "isnan NaN");
cmp_ok(nan(), '!=', nan(), 'nan');
}
@@ -275,4 +273,27 @@ SKIP: {
}
} # SKIP
+SKIP: {
+ skip('no INFINITY', 4) unless defined &INFINITY;
+ # Note that if INFINITY were a bareword, it would be numified to +Inf,
+ # which might confuse following tests.
+ # But this cannot happen as long as "use strict" is effective.
+ ok(isinf(INFINITY), "isinf INFINITY");
+ is(INFINITY, 'Inf', "INFINITY is Perl's Inf");
+ cmp_ok(INFINITY, '>', ($Config{uselongdouble} ? POSIX::LDBL_MAX : POSIX::DBL_MAX),
+ "INFINITY > DBL_MAX");
+ ok(!signbit(INFINITY), "signbit(INFINITY)");
+}
+
+SKIP: {
+ skip('no NAN', 5) unless defined &NAN;
+ ok(isnan(NAN()), "isnan NAN");
+ # Using like() rather than is() is to deal with non-zero payload
+ # (currently this is not the case, but someday Perl might stringify it...)
+ like(NAN, qr/^NaN/, "NAN is Perl's NaN");
+ cmp_ok(NAN, '!=', NAN, "NAN != NAN");
+ ok(!(NAN == NAN), "NAN == NAN");
+ ok(!signbit(NAN), "signbit(NAN)");
+}
+
done_testing();