This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
50dbeda0dfe9ad73d2cf6e69ed3c9acb553cef51
[perl5.git] / t / op / infnan.t
1 #!./perl -w
2
3 BEGIN {
4     chdir 't' if -d 't';
5     @INC = '../lib';
6     require './test.pl';
7 }
8
9 use strict;
10
11 my $PInf = "Inf"  + 0;
12 my $NInf = "-Inf" + 0;
13 my $NaN  = "NaN"  + 0;
14
15 my @PInf = ("Inf", "inf", "INF", "+Inf",
16             "Infinity", "INFINITE",
17             "1.#INF", "1#INF");
18 my @NInf = map { "-$_" } grep { ! /^\+/ } @PInf;
19
20 my @NaN = ("NAN", "nan", "qnan", "SNAN", "NanQ", "NANS",
21            "1.#QNAN", "+1#SNAN", "-1.#NAN", "1#IND",
22            "NaN123", "NAN(123)", "nan%",
23            "nanonano"); # RIP, Robin Williams.
24
25 my @num_fmt = qw(e f g a d u o b x p);
26
27 my $inf_tests = 11 + @num_fmt + 4 + 3 * @PInf + 3 * @NInf + 5 + 3;
28 my $nan_tests =  7 + @num_fmt + 2 + 2 * @NaN + 3;
29
30 my $infnan_tests = 4;
31
32 plan tests => $inf_tests + $nan_tests + $infnan_tests;
33
34 my $has_inf;
35 my $has_nan;
36
37 SKIP: {
38   if ($PInf == 1 && $NInf == 1) {
39     skip $inf_tests, "no infinity found";
40   }
41
42   $has_inf = 1;
43
44   cmp_ok($PInf, '>', 0, "positive infinity");
45   cmp_ok($NInf, '<', 0, "negative infinity");
46
47   cmp_ok($PInf, '>', $NInf, "positive > negative");
48   cmp_ok($NInf, '==', -$PInf, "negative == -positive");
49   cmp_ok(-$NInf, '==', $PInf, "--negative == positive");
50
51   is($PInf,  "Inf", "$PInf value stringifies as Inf");
52   is($NInf, "-Inf", "$NInf value stringifies as -Inf");
53
54   cmp_ok($PInf * 2, '==', $PInf, "twice Inf is Inf");
55   cmp_ok($PInf / 2, '==', $PInf, "half of Inf is Inf");
56
57   is(sprintf("%g", $PInf), "Inf", "$PInf sprintf %g is Inf");
58   is(sprintf("%a", $PInf), "Inf", "$PInf sprintf %a is Inf");
59
60   for my $f (@num_fmt) {
61       is(sprintf("%$f", $PInf), "Inf", "$PInf sprintf %$f is Inf");
62   }
63
64   {
65       local $^W = 0;
66
67       is(sprintf("%c", $PInf), chr(0xFFFD), "$PInf sprintf %c is Inf");
68       is(chr($PInf), chr(0xFFFD), "$PInf chr() is U+FFFD");
69
70       is(sprintf("%c", $NInf), chr(0xFFFD), "$NInf sprintf %c is Inf");
71       is(chr($NInf), chr(0xFFFD), "$NInf chr() is U+FFFD");
72   }
73
74   for my $i (@PInf) {
75     cmp_ok($i + 0 , '==', $PInf, "$i is +Inf");
76     cmp_ok($i, '>', 0, "$i is positive");
77     is("@{[$i+0]}", "Inf", "$i value stringifies as Inf");
78   }
79
80   for my $i (@NInf) {
81     cmp_ok($i + 0, '==', $NInf, "$i is -Inf");
82     cmp_ok($i, '<', 0, "$i is negative");
83     is("@{[$i+0]}", "-Inf", "$i value stringifies as -Inf");
84   }
85
86   is($PInf + $PInf, $PInf, "+inf plus +inf is +inf");
87   is($NInf + $NInf, $NInf, "-inf plus -inf is -inf");
88
89   is(1/$PInf, 0, "one per +Inf is zero");
90   is(1/$NInf, 0, "one per -Inf is zero");
91
92   is(9**9**9, $PInf, "9**9**9 is Inf");
93 }
94
95 {
96     # Silence "isn't numeric in addition", that's kind of the point.
97     local $^W = 0;
98     for my $i (qw(Info Infiniti Infinityz)) {
99         cmp_ok("$i" + 0, '==', 0, "false infinity $i");
100     }
101 }
102
103 SKIP: {
104   if ($NaN == 1) {
105     skip $nan_tests, "no nan found";
106   }
107
108   $has_nan = 1;
109
110   cmp_ok($NaN, '!=', $NaN, "NaN is NaN numerically (by not being NaN)");
111   ok($NaN eq $NaN, "NaN is NaN stringifically");
112
113   is("$NaN", "NaN", "$NaN value stringifies as NaN");
114
115   is("+NaN" + 0, "NaN", "+NaN is NaN");
116   is("-NaN" + 0, "NaN", "-NaN is NaN");
117
118   is($NaN * 2, $NaN, "twice NaN is NaN");
119   is($NaN / 2, $NaN, "half of NaN is NaN");
120
121   for my $f (@num_fmt) {
122       is(sprintf("%$f", $NaN), "NaN", "$NaN sprintf %$f is NaN");
123   }
124
125   {
126       local $^W = 0;
127
128       is(sprintf("%c", $NaN), chr(0xFFFD), "$NaN sprintf %c is Inf");
129       is(chr($NaN), chr(0xFFFD), "$NaN chr() is U+FFFD");
130   }
131
132   for my $i (@NaN) {
133     cmp_ok($i + 0, '!=', $i + 0, "$i is NaN numerically (by not being NaN)");
134     is("@{[$i+0]}", "NaN", "$i value stringifies as NaN");
135   }
136
137   # is() okay with $NaN because it uses eq.
138   is($NaN * 0, $NaN, "NaN times zero is NaN");
139   is($NaN * 2, $NaN, "NaN times two is NaN");
140
141   is(sin(9**9**9), $NaN, "sin(9**9**9) is NaN");
142 }
143
144 SKIP: {
145   unless ($has_inf && $has_nan) {
146     skip $infnan_tests, "no both Inf and Nan";
147   }
148
149   # is() okay with $NaN because it uses eq.
150   is($PInf * 0,     $NaN, "Inf times zero is NaN");
151   is($PInf * $NaN,  $NaN, "Inf times NaN is NaN");
152   is($PInf + $NaN,  $NaN, "Inf plus NaN is NaN");
153   is($PInf - $PInf, $NaN, "Inf minus inf is NaN");
154 }