summaryrefslogtreecommitdiff
path: root/ext/POSIX/t/math.t
diff options
context:
space:
mode:
Diffstat (limited to 'ext/POSIX/t/math.t')
-rw-r--r--ext/POSIX/t/math.t82
1 files changed, 76 insertions, 6 deletions
diff --git a/ext/POSIX/t/math.t b/ext/POSIX/t/math.t
index 7e707532d5..027f8ed544 100644
--- a/ext/POSIX/t/math.t
+++ b/ext/POSIX/t/math.t
@@ -3,6 +3,7 @@
use strict;
use POSIX ':math_h_c99';
+use POSIX ':nan_payload';
use Test::More;
use Config;
@@ -69,13 +70,11 @@ sub near {
}
SKIP: {
- my $C99_SKIP = 59;
-
unless ($Config{d_acosh}) {
- skip "no acosh, suspecting no C99 math", $C99_SKIP;
+ skip "no acosh, suspecting no C99 math";
}
if ($^O =~ /Win32|VMS/) {
- skip "running in $^O, C99 math support uneven", $C99_SKIP;
+ skip "running in $^O, C99 math support uneven";
}
near(M_SQRT2, 1.4142135623731, "M_SQRT2", 1e-9);
near(M_E, 2.71828182845905, "M_E", 1e-9);
@@ -137,8 +136,79 @@ SKIP: {
near(tgamma(9), 40320, "tgamma 9", 1.5e-7);
near(lgamma(9), 10.6046029027452, "lgamma 9", 1.5e-7);
- # If adding more tests here, update also the $C99_SKIP
- # at the beginning of this SKIP block.
+ # These don't work on old mips/hppa platforms because == Inf (or == -Inf).
+ # ok(isnan(setpayload(0)), "setpayload zero");
+ # is(getpayload(setpayload(0)), 0, "setpayload + getpayload (zero)");
+ #
+ # These don't work on most platforms because == Inf (or == -Inf).
+ # ok(isnan(setpayloadsig(0)), "setpayload zero");
+ # is(getpayload(setpayloadsig(0)), 0, "setpayload + getpayload (zero)");
+
+ # Verify that the payload set be setpayload()
+ # (1) still is a nan
+ # (2) but the payload can be retrieved
+ # (3) but is not signaling
+ my $x = 0;
+ setpayload($x, 0x12345);
+ ok(isnan($x), "setpayload + isnan");
+ is(getpayload($x), 0x12345, "setpayload + getpayload");
+ ok(!issignaling($x), "setpayload + issignaling");
+
+ # Verify that the signaling payload set be setpayloadsig()
+ # (1) still is a nan
+ # (2) but the payload can be retrieved
+ # (3) and is signaling
+ setpayloadsig($x, 0x12345);
+ ok(isnan($x), "setpayloadsig + isnan");
+ is(getpayload($x), 0x12345, "setpayload + getpayload");
+ ok(issignaling($x), "setpayloadsig + issignaling");
+
+ # Try a payload more than one byte.
+ is(getpayload(nan(0x12345)), 0x12345, "nan + getpayload");
+
+ # Try payloads of 2^k, most importantly at and beyond 2^32. These
+ # tests will fail if NV is just 32-bit float, but that Should Not
+ # Happen (tm).
+ is(getpayload(nan(2**31)), 2**31, "nan + getpayload 2**31");
+ is(getpayload(nan(2**32)), 2**32, "nan + getpayload 2**32");
+ is(getpayload(nan(2**33)), 2**33, "nan + getpayload 2**33");
+
+ # Payloads just lower than 2^k.
+ is(getpayload(nan(2**31-1)), 2**31-1, "nan + getpayload 2**31-1");
+ is(getpayload(nan(2**32-1)), 2**32-1, "nan + getpayload 2**32-1");
+
+ # Payloads not divisible by two (and larger than 2**32).
+
+ SKIP: {
+ # solaris gets 10460353202 from getpayload() when it should
+ # get 10460353203 (the 3**21). Things go wrong already in
+ # the nan() payload setting: [0x2, 0x6f7c52b4] (ivsize=4)
+ # instead [0x2, 0x6f7c52b3]. Then at getpayload() things
+ # go wrong again, now in other direction: with the (wrong)
+ # [0x2, 0x6f7c52b4] encoded in the nan we should decode into
+ # 10460353204, but we get 10460353202. It doesn't seem to
+ # help even if we use 'unsigned long long' instead of UV/U32
+ # in the POSIX.xs:S_setpayload/S_getpayload.
+ #
+ # casting bug? fmod() bug? Though also broken with
+ # -Duselongdouble + fmodl(), so maybe Solaris cc bug
+ # in general?
+ #
+ # Ironically, the large prime seems to work even in Solaris,
+ # probably just by blind luck.
+ skip($^O, 1) if $^O eq 'solaris';
+ is(getpayload(nan(3**21)), 3**21, "nan + getpayload 3**21");
+ }
+ is(getpayload(nan(4294967311)), 4294967311, "nan + getpayload prime");
+
+ # Truncates towards zero.
+ is(getpayload(nan(1234.567)), 1234, "nan (trunc) + getpayload");
+
+ # Not signaling.
+ ok(!issignaling(0), "issignaling zero");
+ ok(!issignaling(+Inf), "issignaling +Inf");
+ ok(!issignaling(-Inf), "issignaling -Inf");
+ ok(!issignaling(NaN), "issignaling NaN");
} # SKIP
done_testing();