"NaN123", "NAN(123)", "nan%",
"nanonano"); # RIP, Robin Williams.
-my @num_fmt = qw(e f g a d u o b x p);
+my @printf_fmt = qw(e f g a d u o i b x p);
+my @packi_fmt = qw(a A Z b B h H c C s S l L i I n N v V j J w W p P u U);
+my @packf_fmt = qw(f d F);
-my $inf_tests = 13 + @num_fmt + 8 + 3 * @PInf + 3 * @NInf + 14 + 3;
-my $nan_tests = 8 + @num_fmt + 4 + 2 * @NaN + 14;
-
-my $infnan_tests = 13;
-
-plan tests => $inf_tests + 1 + $nan_tests + 1 + $infnan_tests + 1;
+if ($Config{ivsize} == 8) {
+ push @packi_fmt, qw(q Q);
+}
-print "# inf_tests = $inf_tests\n";
-print "# nan_tests = $nan_tests\n";
-print "# infnan_tests = $infnan_tests\n";
+if ($Config{uselongdouble}) {
+ push @packf_fmt, 'D';
+}
-my $has_inf;
-my $has_nan;
+# === Inf tests ===
-SKIP: {
- if ($PInf == 0 && $NInf == 0) {
- skip "no infinity found", $inf_tests;
- }
+cmp_ok($PInf, '>', 0, "positive infinity");
+cmp_ok($NInf, '<', 0, "negative infinity");
- $has_inf = 1;
+cmp_ok($PInf, '>', $NInf, "positive > negative");
+cmp_ok($NInf, '==', -$PInf, "negative == -positive");
+cmp_ok(-$NInf, '==', $PInf, "--negative == positive");
- cmp_ok($PInf, '>', 0, "positive infinity");
- cmp_ok($NInf, '<', 0, "negative infinity");
+is($PInf, "Inf", "$PInf value stringifies as Inf");
+is($NInf, "-Inf", "$NInf value stringifies as -Inf");
- cmp_ok($PInf, '>', $NInf, "positive > negative");
- cmp_ok($NInf, '==', -$PInf, "negative == -positive");
- cmp_ok(-$NInf, '==', $PInf, "--negative == positive");
+cmp_ok($PInf * 2, '==', $PInf, "twice Inf is Inf");
+cmp_ok($PInf / 2, '==', $PInf, "half of Inf is Inf");
- is($PInf, "Inf", "$PInf value stringifies as Inf");
- is($NInf, "-Inf", "$NInf value stringifies as -Inf");
+cmp_ok($PInf + 1, '==', $PInf, "Inf + one is Inf");
+cmp_ok($NInf + 1, '==', $NInf, "-Inf + one is -Inf");
- cmp_ok($PInf * 2, '==', $PInf, "twice Inf is Inf");
- cmp_ok($PInf / 2, '==', $PInf, "half of Inf is Inf");
+is(sprintf("%g", $PInf), "Inf", "$PInf sprintf %g is Inf");
+is(sprintf("%a", $PInf), "Inf", "$PInf sprintf %a is Inf");
- cmp_ok($PInf + 1, '==', $PInf, "Inf + one is Inf");
- cmp_ok($NInf + 1, '==', $NInf, "-Inf + one is -Inf");
+for my $f (@printf_fmt) {
+ is(sprintf("%$f", $PInf), "Inf", "$PInf sprintf %$f is Inf");
+}
- is(sprintf("%g", $PInf), "Inf", "$PInf sprintf %g is Inf");
- is(sprintf("%a", $PInf), "Inf", "$PInf sprintf %a is Inf");
+ok(!defined eval { $a = sprintf("%c", $PInf)}, "sprintf %c +Inf undef");
+like($@, qr/Cannot printf/, "$PInf sprintf fails");
- for my $f (@num_fmt) {
- is(sprintf("%$f", $PInf), "Inf", "$PInf sprintf %$f is Inf");
- }
+ok(!defined eval { $a = chr($PInf) }, "chr(+Inf) undef");
+like($@, qr/Cannot chr/, "+Inf chr() fails");
- {
- local $^W = 0;
+ok(!defined eval { $a = sprintf("%c", $NInf)}, "sprintf %c -Inf undef");
+like($@, qr/Cannot printf/, "$NInf sprintf fails");
- is(sprintf("%c", $PInf), chr(0xFFFD), "$PInf sprintf %c is Inf");
- is(chr($PInf), chr(0xFFFD), "$PInf chr() is U+FFFD");
+ok(!defined eval { $a = chr($NInf) }, "chr(-Inf) undef");
+like($@, qr/Cannot chr/, "-Inf chr() fails");
- is(sprintf("%c", $NInf), chr(0xFFFD), "$NInf sprintf %c is Inf");
- is(chr($NInf), chr(0xFFFD), "$NInf chr() is U+FFFD");
+for my $f (@packi_fmt) {
+ ok(!defined eval { $a = pack($f, $PInf) }, "pack $f +Inf undef");
+ like($@, $f eq 'w' ? qr/Cannot compress Inf/: qr/Cannot pack Inf/,
+ "+Inf pack $f fails");
+ ok(!defined eval { $a = pack($f, $NInf) }, "pack $f -Inf undef");
+ like($@, $f eq 'w' ? qr/Cannot compress -Inf/: qr/Cannot pack -Inf/,
+ "-Inf pack $f fails");
+}
- is(pack('C', $PInf), chr(0xFF), "$PInf pack C is 0xFF byte");
- is(pack('c', $PInf), chr(0xFF), "$PInf pack c is 0xFF byte");
+for my $f (@packf_fmt) {
+ ok(defined eval { $a = pack($f, $PInf) }, "pack $f +Inf defined");
+ eval { $b = unpack($f, $a) };
+ cmp_ok($b, '==', $PInf, "pack $f +Inf equals $PInf");
- is(pack('C', $NInf), chr(0xFF), "$NInf pack C is 0xFF byte");
- is(pack('c', $NInf), chr(0xFF), "$NInf pack c is 0xFF byte");
- }
+ ok(defined eval { $a = pack($f, $NInf) }, "pack $f -Inf defined");
+ eval { $b = unpack($f, $a) };
+ cmp_ok($b, '==', $NInf, "pack $f -Inf equals $NInf");
+}
- for my $i (@PInf) {
+for my $i (@PInf) {
cmp_ok($i + 0 , '==', $PInf, "$i is +Inf");
cmp_ok($i, '>', 0, "$i is positive");
is("@{[$i+0]}", "Inf", "$i value stringifies as Inf");
- }
+}
- for my $i (@NInf) {
+for my $i (@NInf) {
cmp_ok($i + 0, '==', $NInf, "$i is -Inf");
cmp_ok($i, '<', 0, "$i is negative");
is("@{[$i+0]}", "-Inf", "$i value stringifies as -Inf");
- }
+}
- is($PInf + $PInf, $PInf, "+inf plus +inf is +inf");
- is($NInf + $NInf, $NInf, "-inf plus -inf is -inf");
+is($PInf + $PInf, $PInf, "+Inf plus +Inf is +Inf");
+is($NInf + $NInf, $NInf, "-Inf plus -Inf is -Inf");
- is(1/$PInf, 0, "one per +Inf is zero");
- is(1/$NInf, 0, "one per -Inf is zero");
+is(1/$PInf, 0, "one per +Inf is zero");
+is(1/$NInf, 0, "one per -Inf is zero");
- my ($PInfPP, $PInfMM) = ($PInf, $PInf);
- my ($NInfPP, $NInfMM) = ($NInf, $NInf);;
- $PInfPP++;
- $PInfMM--;
- $NInfPP++;
- $NInfMM--;
- is($PInfPP, $PInf, "+inf++ is +inf");
- is($PInfMM, $PInf, "+inf-- is +inf");
- is($NInfPP, $NInf, "-inf++ is -inf");
- is($NInfMM, $NInf, "-inf-- is -inf");
+my ($PInfPP, $PInfMM) = ($PInf, $PInf);
+my ($NInfPP, $NInfMM) = ($NInf, $NInf);;
+$PInfPP++;
+$PInfMM--;
+$NInfPP++;
+$NInfMM--;
+is($PInfPP, $PInf, "+Inf++ is +Inf");
+is($PInfMM, $PInf, "+Inf-- is +Inf");
+is($NInfPP, $NInf, "-Inf++ is -Inf");
+is($NInfMM, $NInf, "-Inf-- is -Inf");
- ok($PInf, "+inf is true");
- ok($NInf, "-inf is true");
+ok($PInf, "+Inf is true");
+ok($NInf, "-Inf is true");
- is(sqrt($PInf), $PInf, "sqrt(+inf) is +inf");
- is(exp($PInf), $PInf, "exp(+inf) is +inf");
- is(exp($NInf), 0, "exp(-inf) is zero");
+is(sqrt($PInf), $PInf, "sqrt(+Inf) is +Inf");
+is(exp($PInf), $PInf, "exp(+Inf) is +Inf");
+is(exp($NInf), 0, "exp(-Inf) is zero");
- SKIP: {
- my $here = "$^O $Config{osvers}";
- if ($here =~ /^hpux 10/) {
- skip "$here: pow doesn't generate Inf", 1;
- }
- is(9**9**9, $PInf, "9**9**9 is Inf");
- }
+SKIP: {
+ my $here = "$^O $Config{osvers}";
+ if ($here =~ /^hpux 10/) {
+ skip "$here: pow doesn't generate Inf", 1;
+ }
+ is(9**9**9, $PInf, "9**9**9 is Inf");
}
SKIP: {
}
}
-is(curr_test() - 1, $inf_tests, "expected number of inf tests");
+# === NaN ===
-SKIP: {
- if ($NaN == 0) {
- skip "no nan found", $nan_tests;
- }
-
- $has_nan = 1;
+cmp_ok($NaN, '!=', $NaN, "NaN is NaN numerically (by not being NaN)");
+ok($NaN eq $NaN, "NaN is NaN stringifically");
- cmp_ok($NaN, '!=', $NaN, "NaN is NaN numerically (by not being NaN)");
- ok($NaN eq $NaN, "NaN is NaN stringifically");
+is("$NaN", "NaN", "$NaN value stringifies as NaN");
- is("$NaN", "NaN", "$NaN value stringifies as NaN");
+is("+NaN" + 0, "NaN", "+NaN is NaN");
+is("-NaN" + 0, "NaN", "-NaN is NaN");
- is("+NaN" + 0, "NaN", "+NaN is NaN");
- is("-NaN" + 0, "NaN", "-NaN is NaN");
+is($NaN * 2, $NaN, "twice NaN is NaN");
+is($NaN / 2, $NaN, "half of NaN is NaN");
- is($NaN * 2, $NaN, "twice NaN is NaN");
- is($NaN / 2, $NaN, "half of NaN is NaN");
+is($NaN + 1, $NaN, "NaN + one is NaN");
- is($NaN + 1, $NaN, "NaN + one is NaN");
+for my $f (@printf_fmt) {
+ is(sprintf("%$f", $NaN), "NaN", "$NaN sprintf %$f is NaN");
+}
- for my $f (@num_fmt) {
- is(sprintf("%$f", $NaN), "NaN", "$NaN sprintf %$f is NaN");
- }
+ok(!defined eval { $a = sprintf("%c", $NaN)}, "sprintf %c NaN undef");
+like($@, qr/Cannot printf/, "$NaN sprintf fails");
- {
- local $^W = 0;
+ok(!defined eval { $a = chr($NaN) }, "chr NaN undef");
+like($@, qr/Cannot chr/, "NaN chr() fails");
- is(sprintf("%c", $NaN), chr(0xFFFD), "$NaN sprintf %c is Inf");
- is(chr($NaN), chr(0xFFFD), "$NaN chr() is U+FFFD");
+for my $f (@packi_fmt) {
+ ok(!defined eval { $a = pack($f, $NaN) }, "pack $f NaN undef");
+ like($@, $f eq 'w' ? qr/Cannot compress NaN/: qr/Cannot pack NaN/,
+ "NaN pack $f fails");
+}
- is(pack('C', $NaN), chr(0xFF), "$NaN pack C is 0xFF byte");
- is(pack('c', $NaN), chr(0xFF), "$NaN pack c is 0xFF");
- }
+for my $f (@packf_fmt) {
+ ok(defined eval { $a = pack($f, $NaN) }, "pack $f NaN defined");
+ eval { $b = unpack($f, $a) };
+ cmp_ok($b, '!=', $b, "pack $f NaN not-equals $NaN");
+}
- for my $i (@NaN) {
+for my $i (@NaN) {
cmp_ok($i + 0, '!=', $i + 0, "$i is NaN numerically (by not being NaN)");
is("@{[$i+0]}", "NaN", "$i value stringifies as NaN");
- }
+}
- ok(!($NaN < 0), "NaN is not lt zero");
- ok(!($NaN == 0), "NaN is not == zero");
- ok(!($NaN > 0), "NaN is not gt zero");
+ok(!($NaN < 0), "NaN is not lt zero");
+ok(!($NaN == 0), "NaN is not == zero");
+ok(!($NaN > 0), "NaN is not gt zero");
- ok(!($NaN < $NaN), "NaN is not lt NaN");
- ok(!($NaN > $NaN), "NaN is not gt NaN");
+ok(!($NaN < $NaN), "NaN is not lt NaN");
+ok(!($NaN > $NaN), "NaN is not gt NaN");
- # is() okay with $NaN because it uses eq.
- is($NaN * 0, $NaN, "NaN times zero is NaN");
- is($NaN * 2, $NaN, "NaN times two is NaN");
+# is() okay with $NaN because it uses eq.
+is($NaN * 0, $NaN, "NaN times zero is NaN");
+is($NaN * 2, $NaN, "NaN times two is NaN");
- my ($NaNPP, $NaNMM) = ($NaN, $NaN);
- $NaNPP++;
- $NaNMM--;
- is($NaNPP, $NaN, "+inf++ is +inf");
- is($NaNMM, $NaN, "+inf-- is +inf");
+my ($NaNPP, $NaNMM) = ($NaN, $NaN);
+$NaNPP++;
+$NaNMM--;
+is($NaNPP, $NaN, "+Inf++ is +Inf");
+is($NaNMM, $NaN, "+Inf-- is +Inf");
- ok($NaN, "NaN is true");
+# You might find this surprising (isn't NaN kind of like of undef?)
+# but this is how it is.
+ok($NaN, "NaN is true");
- is(sqrt($NaN), $NaN, "sqrt(nan) is nan");
- is(exp($NaN), $NaN, "exp(nan) is nan");
- is(sin($NaN), $NaN, "sin(nan) is nan");
+is(sqrt($NaN), $NaN, "sqrt(NaN) is NaN");
+is(exp($NaN), $NaN, "exp(NaN) is NaN");
+is(sin($NaN), $NaN, "sin(NaN) is NaN");
- SKIP: {
- my $here = "$^O $Config{osvers}";
- if ($here =~ /^hpux 10/) {
- skip "$here: 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: {
+ my $here = "$^O $Config{osvers}";
+ if ($here =~ /^hpux 10/) {
+ skip "$here: pow doesn't generate Inf, so sin(Inf) won't happen", 1;
+ }
+ is(sin(9**9**9), $NaN, "sin(9**9**9) is NaN");
}
-is(curr_test() - 1, $inf_tests + 1 + $nan_tests,
- "expected number of nan tests");
+# === Tests combining Inf and NaN ===
-SKIP: {
- unless ($has_inf && $has_nan) {
- skip "no both Inf and Nan", $infnan_tests;
- }
+# is() okay with $NaN because it uses eq.
+is($PInf * 0, $NaN, "Inf times zero is NaN");
+is($PInf * $NaN, $NaN, "Inf times NaN is NaN");
+is($PInf + $NaN, $NaN, "Inf plus NaN is NaN");
+is($PInf - $PInf, $NaN, "Inf minus inf is NaN");
+is($PInf / $PInf, $NaN, "Inf div inf is NaN");
+is($PInf % $PInf, $NaN, "Inf mod inf is NaN");
- # is() okay with $NaN because it uses eq.
- is($PInf * 0, $NaN, "Inf times zero is NaN");
- is($PInf * $NaN, $NaN, "Inf times NaN is NaN");
- is($PInf + $NaN, $NaN, "Inf plus NaN is NaN");
- is($PInf - $PInf, $NaN, "Inf minus inf is NaN");
- is($PInf / $PInf, $NaN, "Inf div inf is NaN");
- is($PInf % $PInf, $NaN, "Inf mod inf is NaN");
+ok(!($NaN < $PInf), "NaN is not lt +Inf");
+ok(!($NaN == $PInf), "NaN is not eq +Inf");
+ok(!($NaN > $PInf), "NaN is not gt +Inf");
- ok(!($NaN < $PInf), "NaN is not lt +inf");
- ok(!($NaN == $PInf), "NaN is not eq +inf");
- ok(!($NaN > $PInf), "NaN is not gt +inf");
+ok(!($NaN > $NInf), "NaN is not lt -Inf");
+ok(!($NaN == $NInf), "NaN is not eq -Inf");
+ok(!($NaN < $NInf), "NaN is not gt -Inf");
- ok(!($NaN > $NInf), "NaN is not lt -inf");
- ok(!($NaN == $NInf), "NaN is not eq -inf");
- ok(!($NaN < $NInf), "NaN is not gt -inf");
-
- is(sin($PInf), $NaN, "sin(+inf) is nan");
-}
+is(sin($PInf), $NaN, "sin(+Inf) is NaN");
-is(curr_test() - 1, $inf_tests + 1 + $nan_tests + 1 + $infnan_tests,
- "expected number of nan tests");
+done_testing();