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