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