1#!./perl 2 3BEGIN { 4 chdir 't' if -d 't'; 5 require './test.pl'; 6 set_up_inc('../lib'); 7} 8 9use strict; 10 11use Config; 12 13plan(tests => 125); 14 15# Test hexfloat literals. 16 17is(0x0p0, 0); 18is(0x0.p0, 0); 19is(0x.0p0, 0); 20is(0x0.0p0, 0); 21is(0x0.00p0, 0); 22 23is(0x1p0, 1); 24is(0x1.p0, 1); 25is(0x1.0p0, 1); 26is(0x1.00p0, 1); 27 28is(0x2p0, 2); 29is(0x2.p0, 2); 30is(0x2.0p0, 2); 31is(0x2.00p0, 2); 32 33is(0x1p1, 2); 34is(0x1.p1, 2); 35is(0x1.0p1, 2); 36is(0x1.00p1, 2); 37 38is(0x.1p0, 0.0625); 39is(0x0.1p0, 0.0625); 40is(0x0.10p0, 0.0625); 41is(0x0.100p0, 0.0625); 42 43is(0x.1p0, 0.0625); 44is(0x1.1p0, 1.0625); 45is(0x1.11p0, 1.06640625); 46is(0x1.111p0, 1.066650390625); 47 48# Positive exponents. 49is(0x1p2, 4); 50is(0x1p+2, 4); 51is(0x0p+0, 0); 52 53# Negative exponents. 54is(0x1p-1, 0.5); 55is(0x1.p-1, 0.5); 56is(0x1.0p-1, 0.5); 57is(0x0p-0, 0); 58 59is(0x1p+2, 4); 60is(0x1p-2, 0.25); 61 62is(0x3p+2, 12); 63is(0x3p-2, 0.75); 64 65# Shifting left. 66is(0x1p2, 1 << 2); 67is(0x1p3, 1 << 3); 68is(0x3p4, 3 << 4); 69is(0x3p5, 3 << 5); 70is(0x12p23, 0x12 << 23); 71 72# Shifting right. 73is(0x1p-2, 1 / (1 << 2)); 74is(0x1p-3, 1 / (1 << 3)); 75is(0x3p-4, 3 / (1 << 4)); 76is(0x3p-5, 3 / (1 << 5)); 77is(0x12p-23, 0x12 / (1 << 23)); 78 79# Negative sign. 80is(-0x1p+2, -4); 81is(-0x1p-2, -0.25); 82is(-0x0p+0, 0); 83is(-0x0p-0, 0); 84 85is(0x0.10p0, 0.0625); 86is(0x0.1p0, 0.0625); 87is(0x.1p0, 0.0625); 88 89is(0x12p+3, 144); 90is(0x12p-3, 2.25); 91 92# Hexdigits (lowercase). 93is(0x9p+0, 9); 94is(0xap+0, 10); 95is(0xfp+0, 15); 96is(0x10p+0, 16); 97is(0x11p+0, 17); 98is(0xabp+0, 171); 99is(0xab.cdp+0, 171.80078125); 100 101# Uppercase hexdigits and exponent prefix. 102is(0xAp+0, 10); 103is(0xFp+0, 15); 104is(0xABP+0, 171); 105is(0xAB.CDP+0, 171.80078125); 106 107# Underbars. 108is(0xa_b.c_dp+1_2, 703696); 109 110# Note that the hexfloat representation is not unique since the 111# exponent can be shifted, and the hexdigits with it: this is no 112# different from 3e4 cf 30e3 cf 30000. The shifting of the hexdigits 113# makes it look stranger, though: 0xap1 == 0x5p2. 114 115# [perl #127183], try some non-canonical forms. 116SKIP: { 117 skip("nv_preserves_uv_bits is $Config{nv_preserves_uv_bits} not 53", 3) 118 unless ($Config{nv_preserves_uv_bits} == 53); 119 is(0x0.b17217f7d1cf78p0, 0x1.62e42fefa39efp-1); 120 is(0x0.58b90bfbe8e7bcp1, 0x1.62e42fefa39efp-1); 121 is(0x0.2c5c85fdf473dep2, 0x1.62e42fefa39efp-1); 122} 123 124# Needs to use within() instead of is() because of long doubles. 125within(0x1.99999999999ap-4, 0.1, 1e-9); 126within(0x3.333333333333p-5, 0.1, 1e-9); 127within(0xc.cccccccccccdp-7, 0.1, 1e-9); 128 129my $warn; 130 131local $SIG{__WARN__} = sub { $warn = shift }; 132 133sub get_warn() { 134 my $save = $warn; 135 undef $warn; 136 return $save; 137} 138 139{ # Test certain things that are not hexfloats and should stay that way. 140 eval '0xp3'; 141 like(get_warn(), qr/Missing operator before p3/); 142 143 eval '5p3'; 144 like(get_warn(), qr/Missing operator before p3/); 145 146 my @a; 147 eval '@a = 0x3..5'; 148 is("@a", "3 4 5"); 149 150 undef $a; 151 eval '$a = eval "0x.3"'; 152 is($a, undef); # throws an error 153 154 undef $a; 155 eval '$a = eval "0xc.3"'; 156 is($a, '123'); 157 158 undef $a; 159 eval '$a = eval "0x.p3"'; 160 is($a, undef); 161} 162 163# Test warnings. 164SKIP: 165{ 166 skip "nv_preserves_uv_bits is $Config{nv_preserves_uv_bits} not 53", 26 167 unless $Config{nv_preserves_uv_bits} == 53; 168 169 local $^W = 1; 170 171 eval '0x1_0000_0000_0000_0p0'; 172 is(get_warn(), undef); 173 174 eval '0x2_0000_0000_0000_0p0'; 175 like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); 176 177 eval '0x1.0000_0000_0000_0p0'; 178 is(get_warn(), undef); 179 180 eval '0x2.0000_0000_0000_0p0'; 181 like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); 182 183 eval '0x.1p-1021'; 184 is(get_warn(), undef); 185 186 eval '0x.1p-1023'; 187 like(get_warn(), qr/^Hexadecimal float: exponent underflow/); 188 189 eval '0x1.fffffffffffffp+1023'; 190 is(get_warn(), undef); 191 192 eval '0x1.fffffffffffffp+1024'; 193 like(get_warn(), qr/^Hexadecimal float: exponent overflow/); 194 195 undef $a; 196 eval '$a = 0x111.0000000000000p+0'; # 12 zeros. 197 like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); 198 is($a, 273); 199 200 # The 13 zeros would be enough to push the hi-order digits 201 # off the high-end. 202 203 undef $a; 204 eval '$a = 0x111.0000000000000p+0'; # 13 zeros. 205 like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); 206 is($a, 273); 207 208 undef $a; 209 eval '$a = 0x111.00000000000000p+0'; # 14 zeros. 210 like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); 211 is($a, 273); 212 213 undef $a; 214 eval '$a = 0xfffffffffffffp0'; # 52 bits. 215 is(get_warn(), undef); 216 is($a, 4.5035996273705e+15); 217 218 undef $a; 219 eval '$a = 0xfffffffffffff.8p0'; # 53 bits. 220 is(get_warn(), undef); 221 is($a, 4.5035996273705e+15); 222 223 undef $a; 224 eval '$a = 0xfffffffffffff.cp0'; # 54 bits. 225 like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); 226 is($a, 4.5035996273705e+15); 227 228 undef $a; 229 eval '$a = 0xf.ffffffffffffp0'; # 52 bits. 230 is(get_warn(), undef); 231 is($a, 16); 232 233 undef $a; 234 eval '$a = 0xf.ffffffffffff8p0'; # 53 bits. 235 is(get_warn(), undef); 236 is($a, 16); 237 238 undef $a; 239 eval '$a = 0xf.ffffffffffffcp0'; # 54 bits. 240 like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); 241 is($a, 16); 242} 243 244# [perl #128919] limited exponent range in hex fp literal with long double 245SKIP: { 246 skip("non-80-bit-long-double", 4) 247 unless ($Config{uselongdouble} && 248 ($Config{nvsize} == 16 || $Config{nvsize} == 12) && 249 ($Config{long_double_style_ieee_extended})); 250 is(0x1p-1074, 4.94065645841246544e-324); 251 is(0x1p-1075, 2.47032822920623272e-324, '[perl #128919]'); 252 is(0x1p-1076, 1.23516411460311636e-324); 253 is(0x1p-16445, 3.6451995318824746e-4951); 254} 255 256# [perl #131894] parsing long binaryish floating point literals used to 257# perform illegal bit shifts. Need 64-bit ints to test. 258SKIP: { 259 skip("non-64-bit NVs or no 64-bit ints to test with", 3) 260 unless $Config{nvsize} == 8 && $Config{d_double_style_ieee} && $Config{use64bitint}; 261 is sprintf("%a", eval("0x030000000000000.1p0")), "0x1.8p+53"; 262 is sprintf("%a", eval("01400000000000000000.1p0")), "0x1.8p+54"; 263 is sprintf("%a", eval("0b110000000000000000000000000000000000000000000000000000000.1p0")), "0x1.8p+56"; 264} 265 266# the implementation also allow for octal and binary fp 267is(01p0, 1); 268is(01.0p0, 1); 269is(01.00p0, 1); 270is(010.1p0, 8.125); 271is(00.400p1, 1); 272is(00p0, 0); 273is(01.1p0, 1.125); 274 275is(0b0p0, 0); 276is(0b1p0, 1); 277is(0b10p0, 2); 278is(0b1.1p0, 1.5); 279 280# previously these would pass "0x..." to the overload instead of the appropriate 281# "0b" or "0" prefix. 282fresh_perl_is(<<'CODE', "1", {}, "overload binary fp"); 283use overload; 284BEGIN { overload::constant float => sub { return eval $_[0]; }; } 285print 0b0.1p1; 286CODE 287 288fresh_perl_is(<<'CODE', "1", {}, "overload octal fp"); 289use overload; 290BEGIN { overload::constant float => sub { return eval $_[0]; }; } 291print 00.1p3; 292CODE 293 294# sprintf %a/%A testing is done in sprintf2.t, 295# trickier than necessary because of long doubles, 296# and because looseness of the spec. 297