xref: /openbsd-src/gnu/usr.bin/perl/cpan/bignum/t/const-bignum.t (revision 256a93a44f36679bee503f12e49566c2183f6181)
1*256a93a4Safresh1# -*- mode: perl; -*-
2*256a93a4Safresh1
3*256a93a4Safresh1# Binary, octal, and hexadecimal floating point literals were introduced in
4*256a93a4Safresh1# v5.22.0.
5*256a93a4Safresh1#
6*256a93a4Safresh1# - It wasn't until v5.28.0 that binary, octal, and hexadecimal floating point
7*256a93a4Safresh1#   literals were converted to the correct value on perls compiled with quadmath
8*256a93a4Safresh1#   support.
9*256a93a4Safresh1#
10*256a93a4Safresh1# - It wasn't until v5.32.0 that binary and octal floating point literals worked
11*256a93a4Safresh1#   correctly with constant overloading. Before v5.32.0, it seems like the
12*256a93a4Safresh1#   second character is always silently converted to an "x", so, e.g., "0b1.1p8"
13*256a93a4Safresh1#   is passed to the overload::constant subroutine as "0x1.1p8", and "01.1p+8"
14*256a93a4Safresh1#   is passed as "0x.1p+8".
15*256a93a4Safresh1#
16*256a93a4Safresh1# - Octal floating point literals using the "0o" prefix were introduced in
17*256a93a4Safresh1#   v5.34.0.
18*256a93a4Safresh1
19*256a93a4Safresh1# Note that all numeric literals that should not be overloaded must be quoted.
20*256a93a4Safresh1
21*256a93a4Safresh1use strict;
22*256a93a4Safresh1use warnings;
23*256a93a4Safresh1
24*256a93a4Safresh1use Test::More tests => "171";
25*256a93a4Safresh1
26*256a93a4Safresh1use bignum;
27*256a93a4Safresh1
28*256a93a4Safresh1my $class = "Math::BigFloat";
29*256a93a4Safresh1my $x;
30*256a93a4Safresh1
31*256a93a4Safresh1################################################################################
32*256a93a4Safresh1# The following tests should be identical for Math::BigInt, Math::BigFloat and
33*256a93a4Safresh1# Math::BigRat.
34*256a93a4Safresh1
35*256a93a4Safresh1# These are handled by "binary".
36*256a93a4Safresh1
37*256a93a4Safresh1$x = 0xff;
38*256a93a4Safresh1is($x, "255", "hexadecimal integer literal 0xff");
39*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
40*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
41*256a93a4Safresh1
42*256a93a4Safresh1SKIP: {
43*256a93a4Safresh1    # Hexadecimal literals using the "0X" prefix require v5.14.0.
44*256a93a4Safresh1    skip "perl v5.14.0 required for hexadecimal integer literals"
45*256a93a4Safresh1      . " with '0X' prefix", "2" if $] < "5.014";
46*256a93a4Safresh1
47*256a93a4Safresh1    $x = eval "0XFF";
48*256a93a4Safresh1    is($x, "255", "hexadecimal integer literal 0XFF");
49*256a93a4Safresh1    like(ref($x), qr/^Math::BigInt(::Lite)?$/,
50*256a93a4Safresh1         "value is a Math::BigInt or Math::BigInt::Lite");
51*256a93a4Safresh1}
52*256a93a4Safresh1
53*256a93a4Safresh1$x = 0377;
54*256a93a4Safresh1is($x, "255", "octal integer literal 0377");
55*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
56*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
57*256a93a4Safresh1
58*256a93a4Safresh1SKIP: {
59*256a93a4Safresh1    # Octal literals using the "0o" prefix require v5.34.0.
60*256a93a4Safresh1    skip "perl v5.34.0 required for octal floating point literals"
61*256a93a4Safresh1      . " with '0o' prefix", "4" if $] < "5.034";
62*256a93a4Safresh1
63*256a93a4Safresh1    for my $str (qw/ 0o377 0O377 /) {
64*256a93a4Safresh1        $x = eval $str;
65*256a93a4Safresh1        is($x, "255", "octal integer literal $str");
66*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
67*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
68*256a93a4Safresh1    }
69*256a93a4Safresh1}
70*256a93a4Safresh1
71*256a93a4Safresh1$x = 0b11111111;
72*256a93a4Safresh1is($x, "255", "binary integer literal 0b11111111");
73*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
74*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
75*256a93a4Safresh1
76*256a93a4Safresh1SKIP: {
77*256a93a4Safresh1    # Binary literals using the "0B" prefix require v5.14.0.
78*256a93a4Safresh1    skip "perl v5.14.0 required for binary integer literals"
79*256a93a4Safresh1      . " with '0B' prefix", "2" if $] < "5.014";
80*256a93a4Safresh1
81*256a93a4Safresh1    $x = eval "0B11111111";
82*256a93a4Safresh1    is($x, "255", "binary integer literal 0B11111111");
83*256a93a4Safresh1    like(ref($x), qr/^Math::BigInt(::Lite)?$/,
84*256a93a4Safresh1         "value is a Math::BigInt or Math::BigInt::Lite");
85*256a93a4Safresh1}
86*256a93a4Safresh1
87*256a93a4Safresh1# These are handled by "float".
88*256a93a4Safresh1
89*256a93a4Safresh1$x = 999999999999999999999999999999999999999999999999999999999999999999999999;
90*256a93a4Safresh1is($x,
91*256a93a4Safresh1   "999999999999999999999999999999999999999999999999999999999999999999999999",
92*256a93a4Safresh1   "decimal integer literal " . ("9" x 72));
93*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
94*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
95*256a93a4Safresh1
96*256a93a4Safresh1$x = 1e72 - 1;
97*256a93a4Safresh1is($x,
98*256a93a4Safresh1   "999999999999999999999999999999999999999999999999999999999999999999999999",
99*256a93a4Safresh1   "literal 1e72 - 1");
100*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
101*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
102*256a93a4Safresh1
103*256a93a4Safresh1# These are handled by "float".
104*256a93a4Safresh1
105*256a93a4Safresh1SKIP: {
106*256a93a4Safresh1    # Hexadecimal floating point literals require v5.28.0.
107*256a93a4Safresh1    skip "perl v5.28.0 required for hexadecimal floating point literals",
108*256a93a4Safresh1      "6" * "2" + "2" * "2" if $] < "5.028";
109*256a93a4Safresh1
110*256a93a4Safresh1    for my $str (qw/ 0x1.3ap+8 0X1.3AP+8
111*256a93a4Safresh1                     0x1.3ap8  0X1.3AP8
112*256a93a4Safresh1                     0x13a0p-4 0X13A0P-4 /)
113*256a93a4Safresh1    {
114*256a93a4Safresh1        $x = eval $str;
115*256a93a4Safresh1        is($x, "314", "hexadecimal floating point literal $str");
116*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
117*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
118*256a93a4Safresh1    }
119*256a93a4Safresh1
120*256a93a4Safresh1    for my $str (qw/ 0x0.0p+8 0X0.0P+8 /)
121*256a93a4Safresh1    {
122*256a93a4Safresh1        $x = eval $str;
123*256a93a4Safresh1        is($x, "0", "hexadecimal floating point literal $str");
124*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
125*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
126*256a93a4Safresh1    }
127*256a93a4Safresh1}
128*256a93a4Safresh1
129*256a93a4Safresh1SKIP: {
130*256a93a4Safresh1    # Octal floating point literals using the "0o" prefix require v5.34.0.
131*256a93a4Safresh1    skip "perl v5.34.0 required for octal floating point literals"
132*256a93a4Safresh1      . " with '0o' prefix", "6" * "2" + "6" * "2" if $] < "5.034";
133*256a93a4Safresh1
134*256a93a4Safresh1    for my $str (qw/ 0o1.164p+8 0O1.164P+8
135*256a93a4Safresh1                     0o1.164p8  0O1.164P8
136*256a93a4Safresh1                     0o11640p-4 0O11640P-4 /)
137*256a93a4Safresh1    {
138*256a93a4Safresh1        $x = eval $str;
139*256a93a4Safresh1        is($x, "314", "octal floating point literal $str");
140*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
141*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
142*256a93a4Safresh1    }
143*256a93a4Safresh1
144*256a93a4Safresh1    for my $str (qw/ 0o0.0p+8 0O0.0P+8
145*256a93a4Safresh1                     0o0.0p8  0O0.0P8
146*256a93a4Safresh1                     0o0.0p-8 0O0.0P-8 /)
147*256a93a4Safresh1    {
148*256a93a4Safresh1        $x = eval $str;
149*256a93a4Safresh1        is($x, "0", "octal floating point literal $str");
150*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
151*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
152*256a93a4Safresh1    }
153*256a93a4Safresh1}
154*256a93a4Safresh1
155*256a93a4Safresh1SKIP: {
156*256a93a4Safresh1    # Octal floating point literals using the "0" prefix require v5.32.0.
157*256a93a4Safresh1    skip "perl v5.32.0 required for octal floating point literals",
158*256a93a4Safresh1      "6" * "2" + "6" * "2" if $] < "5.032";
159*256a93a4Safresh1
160*256a93a4Safresh1    for my $str (qw/ 01.164p+8 01.164P+8
161*256a93a4Safresh1                     01.164p8  01.164P8
162*256a93a4Safresh1                     011640p-4 011640P-4 /)
163*256a93a4Safresh1    {
164*256a93a4Safresh1        $x = eval $str;
165*256a93a4Safresh1        is($x, "314", "octal floating point literal $str");
166*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
167*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
168*256a93a4Safresh1    }
169*256a93a4Safresh1
170*256a93a4Safresh1    for my $str (qw/ 00.0p+8 00.0P+8
171*256a93a4Safresh1                     00.0p8 00.0P8
172*256a93a4Safresh1                     00.0p-8 00.0P-8 /)
173*256a93a4Safresh1    {
174*256a93a4Safresh1        $x = eval $str;
175*256a93a4Safresh1        is($x, "0", "octal floating point literal $str");
176*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
177*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
178*256a93a4Safresh1    }
179*256a93a4Safresh1}
180*256a93a4Safresh1
181*256a93a4Safresh1SKIP: {
182*256a93a4Safresh1    # Binary floating point literals require v5.32.0.
183*256a93a4Safresh1    skip "perl v5.32.0 required for binary floating point literals",
184*256a93a4Safresh1      "6" * "2" + "6" * "2" if $] < "5.032";
185*256a93a4Safresh1
186*256a93a4Safresh1    for my $str (qw/ 0b1.0011101p+8   0B1.0011101P+8
187*256a93a4Safresh1                     0b1.0011101p8    0B1.0011101P8
188*256a93a4Safresh1                     0b10011101000p-2 0B10011101000P-2 /)
189*256a93a4Safresh1    {
190*256a93a4Safresh1        $x = eval $str;
191*256a93a4Safresh1        is($x, "314", "binary floating point literal $str");
192*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
193*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
194*256a93a4Safresh1    }
195*256a93a4Safresh1
196*256a93a4Safresh1    for my $str (qw/ 0b0p+8 0B0P+8
197*256a93a4Safresh1                     0b0p8 0B0P8
198*256a93a4Safresh1                     0b0p-8 0B0P-8
199*256a93a4Safresh1                   /)
200*256a93a4Safresh1    {
201*256a93a4Safresh1        $x = eval $str;
202*256a93a4Safresh1        is($x, "0", "binary floating point literal $str");
203*256a93a4Safresh1        like(ref($x), qr/^Math::BigInt(::Lite)?$/,
204*256a93a4Safresh1             "value is a Math::BigInt or Math::BigInt::Lite");
205*256a93a4Safresh1    }
206*256a93a4Safresh1}
207*256a93a4Safresh1
208*256a93a4Safresh1# These are handled by "integer".
209*256a93a4Safresh1
210*256a93a4Safresh1$x = 314;
211*256a93a4Safresh1is($x, "314", "integer literal 314");
212*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
213*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
214*256a93a4Safresh1
215*256a93a4Safresh1$x = 0;
216*256a93a4Safresh1is($x, "0", "integer literal 0");
217*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
218*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
219*256a93a4Safresh1
220*256a93a4Safresh1$x = 2 ** 255;
221*256a93a4Safresh1is($x,
222*256a93a4Safresh1   "578960446186580977117854925043439539266"
223*256a93a4Safresh1   . "34992332820282019728792003956564819968",
224*256a93a4Safresh1   "2 ** 255");
225*256a93a4Safresh1like(ref($x), qr/^Math::BigInt(::Lite)?$/,
226*256a93a4Safresh1     "value is a Math::BigInt or Math::BigInt::Lite");
227*256a93a4Safresh1
228*256a93a4Safresh1# These are handled by "binary".
229*256a93a4Safresh1
230*256a93a4Safresh1{
231*256a93a4Safresh1    no warnings "portable";     # protect against "non-portable" warnings
232*256a93a4Safresh1
233*256a93a4Safresh1    # hexadecimal constant
234*256a93a4Safresh1    $x = 0x123456789012345678901234567890;
235*256a93a4Safresh1    is($x,
236*256a93a4Safresh1       "94522879687365475552814062743484560",
237*256a93a4Safresh1       "hexadecimal constant 0x123456789012345678901234567890");
238*256a93a4Safresh1    like(ref($x), qr/^Math::BigInt(::Lite)?$/,
239*256a93a4Safresh1         "value is a Math::BigInt or Math::BigInt::Lite");
240*256a93a4Safresh1
241*256a93a4Safresh1    # octal constant
242*256a93a4Safresh1    $x = 012345676543210123456765432101234567654321;
243*256a93a4Safresh1    is($x,
244*256a93a4Safresh1       "1736132869400711976876385488263403729",
245*256a93a4Safresh1       "octal constant 012345676543210123456765432101234567654321");
246*256a93a4Safresh1    like(ref($x), qr/^Math::BigInt(::Lite)?$/,
247*256a93a4Safresh1         "value is a Math::BigInt or Math::BigInt::Lite");
248*256a93a4Safresh1
249*256a93a4Safresh1    # binary constant
250*256a93a4Safresh1    $x = 0b01010100011001010110110001110011010010010110000101101101;
251*256a93a4Safresh1    is($x,
252*256a93a4Safresh1       "23755414508757357",
253*256a93a4Safresh1       "binary constant 0b0101010001100101011011000111"
254*256a93a4Safresh1       . "0011010010010110000101101101");
255*256a93a4Safresh1    like(ref($x), qr/^Math::BigInt(::Lite)?$/,
256*256a93a4Safresh1         "value is a Math::BigInt or Math::BigInt::Lite");
257*256a93a4Safresh1}
258*256a93a4Safresh1
259*256a93a4Safresh1################################################################################
260*256a93a4Safresh1# The following tests are unique to $class.
261*256a93a4Safresh1
262*256a93a4Safresh1# These are handled by "float".
263*256a93a4Safresh1
264*256a93a4Safresh1$x = 0.999999999999999999999999999999999999999999999999999999999999999999999999;
265*256a93a4Safresh1is($x,
266*256a93a4Safresh1   "0.999999999999999999999999999999999999999999999999999999999999999999999999",
267*256a93a4Safresh1   "decimal floating point literal 0." . ("9" x 72));
268*256a93a4Safresh1is(ref($x), $class, "value is a $class");
269*256a93a4Safresh1
270*256a93a4Safresh1$x = 1e72 - 0.1;
271*256a93a4Safresh1is($x,
272*256a93a4Safresh1   "999999999999999999999999999999999999999999999999999999999999999999999999.9",
273*256a93a4Safresh1   "literal 1e72 - 0.1");
274*256a93a4Safresh1is(ref($x), $class, "value is a $class");
275*256a93a4Safresh1
276*256a93a4Safresh1# These are handled by "float".
277*256a93a4Safresh1
278*256a93a4Safresh1SKIP: {
279*256a93a4Safresh1    # Hexadecimal floating point literals require v5.28.0.
280*256a93a4Safresh1    skip "perl v5.22.0 required for hexadecimal floating point literals",
281*256a93a4Safresh1      "6" * "2" if $] < "5.028";
282*256a93a4Safresh1
283*256a93a4Safresh1    for my $str (qw/ 0x1.92p+1 0X1.92P+1
284*256a93a4Safresh1                     0x1.92p1 0X1.92P1
285*256a93a4Safresh1                     0x19.2p-3 0X19.2P-3 /)
286*256a93a4Safresh1    {
287*256a93a4Safresh1        $x = eval $str;
288*256a93a4Safresh1        is($x, "3.140625", "hexadecimal floating point literal $str");
289*256a93a4Safresh1        is(ref($x), $class, "value is a $class");
290*256a93a4Safresh1    }
291*256a93a4Safresh1}
292*256a93a4Safresh1
293*256a93a4Safresh1SKIP: {
294*256a93a4Safresh1    # Octal floating point literals using the "0o" prefix require v5.34.0.
295*256a93a4Safresh1    skip "perl v5.34.0 required for octal floating point literals"
296*256a93a4Safresh1      . " with '0o' prefix", "6" * "2" if $] < "5.034";
297*256a93a4Safresh1
298*256a93a4Safresh1    for my $str (qw/ 0o1.444p+1 0O1.444P+1
299*256a93a4Safresh1                     0o1.444p1  0O1.444P1
300*256a93a4Safresh1                     0o14.44p-2 0O14.44P-2 /)
301*256a93a4Safresh1    {
302*256a93a4Safresh1        $x = eval $str;
303*256a93a4Safresh1        is($x, "3.140625", "octal floating point literal $str");
304*256a93a4Safresh1        is(ref($x), $class, "value is a $class");
305*256a93a4Safresh1    }
306*256a93a4Safresh1}
307*256a93a4Safresh1
308*256a93a4Safresh1SKIP: {
309*256a93a4Safresh1    # Octal floating point literals using the "0" prefix require v5.32.0.
310*256a93a4Safresh1    skip "perl v5.32.0 required for octal floating point literals",
311*256a93a4Safresh1      "6" * "2" if $] < "5.032";
312*256a93a4Safresh1
313*256a93a4Safresh1    for my $str (qw/ 01.444p+1 01.444P+1
314*256a93a4Safresh1                     01.444p1  01.444P1
315*256a93a4Safresh1                     014.44p-2 014.44P-2 /)
316*256a93a4Safresh1    {
317*256a93a4Safresh1        $x = eval $str;
318*256a93a4Safresh1        is($x, "3.140625", "octal floating point literal $str");
319*256a93a4Safresh1        is(ref($x), $class, "value is a $class");
320*256a93a4Safresh1    }
321*256a93a4Safresh1}
322*256a93a4Safresh1
323*256a93a4Safresh1SKIP: {
324*256a93a4Safresh1    # Binary floating point literals require v5.32.0.
325*256a93a4Safresh1    skip "perl v5.32.0 required for binary floating point literals",
326*256a93a4Safresh1      "6" * "2" if $] < "5.032";
327*256a93a4Safresh1
328*256a93a4Safresh1    for my $str (qw/ 0b1.1001001p+1 0B1.1001001P+1
329*256a93a4Safresh1                     0b1.1001001p1  0B1.1001001P1
330*256a93a4Safresh1                     0b110.01001p-1 0B110.01001P-1 /)
331*256a93a4Safresh1    {
332*256a93a4Safresh1        $x = eval $str;
333*256a93a4Safresh1        is($x, "3.140625", "binary floating point literal $str");
334*256a93a4Safresh1        is(ref($x), $class, "value is a $class");
335*256a93a4Safresh1    }
336*256a93a4Safresh1}
337*256a93a4Safresh1
338*256a93a4Safresh1is(1.0 / 3.0, "0.3333333333333333333333333333333333333333",
339*256a93a4Safresh1   "1.0 / 3.0 = 0.3333333333333333333333333333333333333333");
340