|
2 | 2 |
|
3 | 3 | from testutils import assert_raises
|
4 | 4 |
|
| 5 | +NAN = float('nan') |
| 6 | +INF = float('inf') |
| 7 | +NINF = float('-inf') |
| 8 | + |
5 | 9 | 1 + 1.1
|
6 | 10 |
|
7 | 11 | a = 1.2
|
|
240 | 244 | with assert_raises(SyntaxError):
|
241 | 245 | exec(src)
|
242 | 246 |
|
243 |
| -assert float.fromhex('0.0') == 0.0 |
244 |
| -assert float.fromhex('-0.0') == 0.0 |
245 |
| -assert float.fromhex('0x0p0') == 0.0 |
246 |
| -assert float.fromhex('0x010p0') == 16.0 |
247 |
| -assert float.fromhex('0x0.10p3') == 0.5 |
248 |
| -assert float.fromhex('-0x0p0') == 0.0 |
249 |
| -assert float.fromhex('0x0.p0') == 0.0 |
250 |
| -assert float.fromhex('-0x0.p0') == 0.0 |
251 |
| -assert float.fromhex('0x0.0p+0') == 0.0 |
252 |
| -assert float.fromhex('-0x0.0p+0') == -0.0 |
253 |
| -assert float.fromhex('0x1.000000p+0') == 1.0 |
254 |
| -assert float.fromhex('-0x1.800000p+0') == -1.5 |
255 |
| -assert float.fromhex('inf') == float('inf') |
256 |
| -assert math.isnan(float.fromhex('nan')) |
257 |
| -assert_raises(ValueError, lambda: float.fromhex('error')) |
| 247 | +fromHex = float.fromhex |
| 248 | +def identical(x, y): |
| 249 | + if math.isnan(x) or math.isnan(y): |
| 250 | + if math.isnan(x) == math.isnan(y): |
| 251 | + return |
| 252 | + elif x == y and (x != 0.0 or math.copysign(1.0, x) == math.copysign(1.0, y)): |
| 253 | + return |
| 254 | + raise SyntaxError(f"{x} not identical to {y}") |
| 255 | + |
| 256 | +invalid_inputs = [ |
| 257 | + "infi", # misspelt infinities and nans |
| 258 | + "-Infinit", |
| 259 | + "++inf", |
| 260 | + "-+Inf", |
| 261 | + "--nan", |
| 262 | + "+-NaN", |
| 263 | + "snan", |
| 264 | + "NaNs", |
| 265 | + "nna", |
| 266 | + "an", |
| 267 | + "nf", |
| 268 | + "nfinity", |
| 269 | + "inity", |
| 270 | + "iinity", |
| 271 | + "0xnan", |
| 272 | + "", |
| 273 | + " ", |
| 274 | + "x1.0p0", |
| 275 | + "0xX1.0p0", |
| 276 | + "+ 0x1.0p0", # internal whitespace |
| 277 | + "- 0x1.0p0", |
| 278 | + "0 x1.0p0", |
| 279 | + "0x 1.0p0", |
| 280 | + "0x1 2.0p0", |
| 281 | + "+0x1 .0p0", |
| 282 | + "0x1. 0p0", |
| 283 | + "-0x1.0 1p0", |
| 284 | + "-0x1.0 p0", |
| 285 | + "+0x1.0p +0", |
| 286 | + "0x1.0p -0", |
| 287 | + "0x1.0p 0", |
| 288 | + "+0x1.0p+ 0", |
| 289 | + "-0x1.0p- 0", |
| 290 | + "++0x1.0p-0", # double signs |
| 291 | + "--0x1.0p0", |
| 292 | + "+-0x1.0p+0", |
| 293 | + "-+0x1.0p0", |
| 294 | + "0x1.0p++0", |
| 295 | + "+0x1.0p+-0", |
| 296 | + "-0x1.0p-+0", |
| 297 | + "0x1.0p--0", |
| 298 | + "0x1.0.p0", |
| 299 | + "0x.p0", # no hex digits before or after point |
| 300 | + "0x1,p0", # wrong decimal point character |
| 301 | + "0x1pa", |
| 302 | + "0x1p\uff10", # fullwidth Unicode digits |
| 303 | + "\uff10x1p0", |
| 304 | + "0x\uff11p0", |
| 305 | + "0x1.\uff10p0", |
| 306 | + "0x1p0 \n 0x2p0", |
| 307 | + "0x1p0\0 0x1p0", # embedded null byte is not end of string |
| 308 | +] |
| 309 | + |
| 310 | +for x in invalid_inputs: |
| 311 | + assert_raises(ValueError, lambda: fromHex(x)) |
| 312 | + |
| 313 | +value_pairs = [ |
| 314 | + ("inf", INF), |
| 315 | + ("-Infinity", -INF), |
| 316 | + ("NaN", NAN), |
| 317 | + ("1.0", 1.0), |
| 318 | + ("-0x.2", -0.125), |
| 319 | + ("-0.0", -0.0), |
| 320 | +] |
| 321 | +whitespace = [ |
| 322 | + "", |
| 323 | + " ", |
| 324 | + "\t", |
| 325 | + "\n", |
| 326 | + "\n \t", |
| 327 | + "\f", |
| 328 | + "\v", |
| 329 | + "\r" |
| 330 | +] |
| 331 | + |
| 332 | +for inp, expected in value_pairs: |
| 333 | + for lead in whitespace: |
| 334 | + for trail in whitespace: |
| 335 | + got = fromHex(lead + inp + trail) |
| 336 | + identical(got, expected) |
| 337 | + |
| 338 | +MAX = fromHex('0x.fffffffffffff8p+1024') # max normal |
| 339 | +MIN = fromHex('0x1p-1022') # min normal |
| 340 | +TINY = fromHex('0x0.0000000000001p-1022') # min subnormal |
| 341 | +EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up |
| 342 | + |
| 343 | +# two spellings of infinity, with optional signs; case-insensitive |
| 344 | +identical(fromHex('inf'), INF) |
| 345 | +identical(fromHex('+Inf'), INF) |
| 346 | +identical(fromHex('-INF'), -INF) |
| 347 | +identical(fromHex('iNf'), INF) |
| 348 | +identical(fromHex('Infinity'), INF) |
| 349 | +identical(fromHex('+INFINITY'), INF) |
| 350 | +identical(fromHex('-infinity'), -INF) |
| 351 | +identical(fromHex('-iNFiNitY'), -INF) |
| 352 | + |
| 353 | +# nans with optional sign; case insensitive |
| 354 | +identical(fromHex('nan'), NAN) |
| 355 | +identical(fromHex('+NaN'), NAN) |
| 356 | +identical(fromHex('-NaN'), NAN) |
| 357 | +identical(fromHex('-nAN'), NAN) |
| 358 | + |
| 359 | +# variations in input format |
| 360 | +identical(fromHex('1'), 1.0) |
| 361 | +identical(fromHex('+1'), 1.0) |
| 362 | +identical(fromHex('1.'), 1.0) |
| 363 | +identical(fromHex('1.0'), 1.0) |
| 364 | +identical(fromHex('1.0p0'), 1.0) |
| 365 | +identical(fromHex('01'), 1.0) |
| 366 | +identical(fromHex('01.'), 1.0) |
| 367 | +identical(fromHex('0x1'), 1.0) |
| 368 | +identical(fromHex('0x1.'), 1.0) |
| 369 | +identical(fromHex('0x1.0'), 1.0) |
| 370 | +identical(fromHex('+0x1.0'), 1.0) |
| 371 | +identical(fromHex('0x1p0'), 1.0) |
| 372 | +identical(fromHex('0X1p0'), 1.0) |
| 373 | +identical(fromHex('0X1P0'), 1.0) |
| 374 | +identical(fromHex('0x1P0'), 1.0) |
| 375 | +identical(fromHex('0x1.p0'), 1.0) |
| 376 | +identical(fromHex('0x1.0p0'), 1.0) |
| 377 | +identical(fromHex('0x.1p4'), 1.0) |
| 378 | +identical(fromHex('0x.1p04'), 1.0) |
| 379 | +identical(fromHex('0x.1p004'), 1.0) |
| 380 | +identical(fromHex('0x1p+0'), 1.0) |
| 381 | +identical(fromHex('0x1P-0'), 1.0) |
| 382 | +identical(fromHex('+0x1p0'), 1.0) |
| 383 | +identical(fromHex('0x01p0'), 1.0) |
| 384 | +identical(fromHex('0x1p00'), 1.0) |
| 385 | +identical(fromHex(' 0x1p0 '), 1.0) |
| 386 | +identical(fromHex('\n 0x1p0'), 1.0) |
| 387 | +identical(fromHex('0x1p0 \t'), 1.0) |
| 388 | +identical(fromHex('0xap0'), 10.0) |
| 389 | +identical(fromHex('0xAp0'), 10.0) |
| 390 | +identical(fromHex('0xaP0'), 10.0) |
| 391 | +identical(fromHex('0xAP0'), 10.0) |
| 392 | +identical(fromHex('0xbep0'), 190.0) |
| 393 | +identical(fromHex('0xBep0'), 190.0) |
| 394 | +identical(fromHex('0xbEp0'), 190.0) |
| 395 | +identical(fromHex('0XBE0P-4'), 190.0) |
| 396 | +identical(fromHex('0xBEp0'), 190.0) |
| 397 | +identical(fromHex('0xB.Ep4'), 190.0) |
| 398 | +identical(fromHex('0x.BEp8'), 190.0) |
| 399 | +identical(fromHex('0x.0BEp12'), 190.0) |
| 400 | + |
| 401 | +# moving the point around |
| 402 | +pi = fromHex('0x1.921fb54442d18p1') |
| 403 | +identical(fromHex('0x.006487ed5110b46p11'), pi) |
| 404 | +identical(fromHex('0x.00c90fdaa22168cp10'), pi) |
| 405 | +identical(fromHex('0x.01921fb54442d18p9'), pi) |
| 406 | +identical(fromHex('0x.03243f6a8885a3p8'), pi) |
| 407 | +identical(fromHex('0x.06487ed5110b46p7'), pi) |
| 408 | +identical(fromHex('0x.0c90fdaa22168cp6'), pi) |
| 409 | +identical(fromHex('0x.1921fb54442d18p5'), pi) |
| 410 | +identical(fromHex('0x.3243f6a8885a3p4'), pi) |
| 411 | +identical(fromHex('0x.6487ed5110b46p3'), pi) |
| 412 | +identical(fromHex('0x.c90fdaa22168cp2'), pi) |
| 413 | +identical(fromHex('0x1.921fb54442d18p1'), pi) |
| 414 | +identical(fromHex('0x3.243f6a8885a3p0'), pi) |
| 415 | +identical(fromHex('0x6.487ed5110b46p-1'), pi) |
| 416 | +identical(fromHex('0xc.90fdaa22168cp-2'), pi) |
| 417 | +identical(fromHex('0x19.21fb54442d18p-3'), pi) |
| 418 | +identical(fromHex('0x32.43f6a8885a3p-4'), pi) |
| 419 | +identical(fromHex('0x64.87ed5110b46p-5'), pi) |
| 420 | +identical(fromHex('0xc9.0fdaa22168cp-6'), pi) |
| 421 | +identical(fromHex('0x192.1fb54442d18p-7'), pi) |
| 422 | +identical(fromHex('0x324.3f6a8885a3p-8'), pi) |
| 423 | +identical(fromHex('0x648.7ed5110b46p-9'), pi) |
| 424 | +identical(fromHex('0xc90.fdaa22168cp-10'), pi) |
| 425 | +identical(fromHex('0x1921.fb54442d18p-11'), pi) |
| 426 | +identical(fromHex('0x1921fb54442d1.8p-47'), pi) |
| 427 | +identical(fromHex('0x3243f6a8885a3p-48'), pi) |
| 428 | +identical(fromHex('0x6487ed5110b46p-49'), pi) |
| 429 | +identical(fromHex('0xc90fdaa22168cp-50'), pi) |
| 430 | +identical(fromHex('0x1921fb54442d18p-51'), pi) |
| 431 | +identical(fromHex('0x3243f6a8885a30p-52'), pi) |
| 432 | +identical(fromHex('0x6487ed5110b460p-53'), pi) |
| 433 | +identical(fromHex('0xc90fdaa22168c0p-54'), pi) |
| 434 | +identical(fromHex('0x1921fb54442d180p-55'), pi) |
258 | 435 |
|
259 | 436 | assert (0.0).hex() == '0x0.0p+0'
|
260 | 437 | assert (-0.0).hex() == '-0x0.0p+0'
|
|
264 | 441 | assert float('-inf').hex() == '-inf'
|
265 | 442 | assert float('nan').hex() == 'nan'
|
266 | 443 |
|
267 |
| -#for _ in range(10000): |
268 |
| -# f = random.random() * random.randint(0, 0x10000000000000000) |
269 |
| -# assert f == float.fromhex(f.hex()) |
270 |
| - |
271 | 444 | # Test float exponent:
|
272 | 445 | assert 1 if 1else 0 == 1
|
273 | 446 |
|
|
0 commit comments