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