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