1import fractions 2import operator 3import os 4import random 5import sys 6import struct 7import time 8import unittest 9 10from test import support 11from test.support.testcase import FloatsAreIdenticalMixin 12from test.test_grammar import (VALID_UNDERSCORE_LITERALS, 13 INVALID_UNDERSCORE_LITERALS) 14from math import isinf, isnan, copysign, ldexp 15import math 16 17try: 18 import _testcapi 19except ImportError: 20 _testcapi = None 21 22INF = float("inf") 23NAN = float("nan") 24 25 26#locate file with float format test values 27test_dir = os.path.dirname(__file__) or os.curdir 28format_testfile = os.path.join(test_dir, 'mathdata', 'formatfloat_testcases.txt') 29 30class FloatSubclass(float): 31 pass 32 33class OtherFloatSubclass(float): 34 pass 35 36class GeneralFloatCases(unittest.TestCase): 37 38 def test_float(self): 39 self.assertEqual(float(3.14), 3.14) 40 self.assertEqual(float(314), 314.0) 41 self.assertEqual(float(" 3.14 "), 3.14) 42 self.assertRaises(ValueError, float, " 0x3.1 ") 43 self.assertRaises(ValueError, float, " -0x3.p-1 ") 44 self.assertRaises(ValueError, float, " +0x3.p-1 ") 45 self.assertRaises(ValueError, float, "++3.14") 46 self.assertRaises(ValueError, float, "+-3.14") 47 self.assertRaises(ValueError, float, "-+3.14") 48 self.assertRaises(ValueError, float, "--3.14") 49 self.assertRaises(ValueError, float, ".nan") 50 self.assertRaises(ValueError, float, "+.inf") 51 self.assertRaises(ValueError, float, ".") 52 self.assertRaises(ValueError, float, "-.") 53 self.assertRaises(TypeError, float, {}) 54 self.assertRaisesRegex(TypeError, "not 'dict'", float, {}) 55 # Lone surrogate 56 self.assertRaises(ValueError, float, '\uD8F0') 57 # check that we don't accept alternate exponent markers 58 self.assertRaises(ValueError, float, "-1.7d29") 59 self.assertRaises(ValueError, float, "3D-14") 60 self.assertEqual(float(" \u0663.\u0661\u0664 "), 3.14) 61 self.assertEqual(float("\N{EM SPACE}3.14\N{EN SPACE}"), 3.14) 62 # extra long strings should not be a problem 63 float(b'.' + b'1'*1000) 64 float('.' + '1'*1000) 65 # Invalid unicode string 66 # See bpo-34087 67 self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f') 68 69 def test_noargs(self): 70 self.assertEqual(float(), 0.0) 71 72 def test_underscores(self): 73 for lit in VALID_UNDERSCORE_LITERALS: 74 if not any(ch in lit for ch in 'jJxXoObB'): 75 self.assertEqual(float(lit), eval(lit)) 76 self.assertEqual(float(lit), float(lit.replace('_', ''))) 77 for lit in INVALID_UNDERSCORE_LITERALS: 78 if lit in ('0_7', '09_99'): # octals are not recognized here 79 continue 80 if not any(ch in lit for ch in 'jJxXoObB'): 81 self.assertRaises(ValueError, float, lit) 82 # Additional test cases; nan and inf are never valid as literals, 83 # only in the float() constructor, but we don't allow underscores 84 # in or around them. 85 self.assertRaises(ValueError, float, '_NaN') 86 self.assertRaises(ValueError, float, 'Na_N') 87 self.assertRaises(ValueError, float, 'IN_F') 88 self.assertRaises(ValueError, float, '-_INF') 89 self.assertRaises(ValueError, float, '-INF_') 90 # Check that we handle bytes values correctly. 91 self.assertRaises(ValueError, float, b'0_.\xff9') 92 93 def test_non_numeric_input_types(self): 94 # Test possible non-numeric types for the argument x, including 95 # subclasses of the explicitly documented accepted types. 96 class CustomStr(str): pass 97 class CustomBytes(bytes): pass 98 class CustomByteArray(bytearray): pass 99 100 factories = [ 101 bytes, 102 bytearray, 103 lambda b: CustomStr(b.decode()), 104 CustomBytes, 105 CustomByteArray, 106 memoryview, 107 ] 108 try: 109 from array import array 110 except ImportError: 111 pass 112 else: 113 factories.append(lambda b: array('B', b)) 114 115 for f in factories: 116 x = f(b" 3.14 ") 117 with self.subTest(type(x)): 118 self.assertEqual(float(x), 3.14) 119 with self.assertRaisesRegex(ValueError, "could not convert"): 120 float(f(b'A' * 0x10)) 121 122 def test_float_memoryview(self): 123 self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3) 124 self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3) 125 self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3) 126 self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3) 127 self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3) 128 129 def test_error_message(self): 130 def check(s): 131 with self.assertRaises(ValueError, msg='float(%r)' % (s,)) as cm: 132 float(s) 133 self.assertEqual(str(cm.exception), 134 'could not convert string to float: %r' % (s,)) 135 136 check('\xbd') 137 check('123\xbd') 138 check(' 123 456 ') 139 check(b' 123 456 ') 140 # all whitespace (cf. https://github.com/python/cpython/issues/95605) 141 check('') 142 check(' ') 143 check('\t \n') 144 145 # non-ascii digits (error came from non-digit '!') 146 check('\u0663\u0661\u0664!') 147 # embedded NUL 148 check('123\x00') 149 check('123\x00 245') 150 check('123\x00245') 151 # byte string with embedded NUL 152 check(b'123\x00') 153 # non-UTF-8 byte string 154 check(b'123\xa0') 155 156 @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE', '') 157 def test_float_with_comma(self): 158 # set locale to something that doesn't use '.' for the decimal point 159 # float must not accept the locale specific decimal point but 160 # it still has to accept the normal python syntax 161 import locale 162 if not locale.localeconv()['decimal_point'] == ',': 163 self.skipTest('decimal_point is not ","') 164 165 self.assertEqual(float(" 3.14 "), 3.14) 166 self.assertEqual(float("+3.14 "), 3.14) 167 self.assertEqual(float("-3.14 "), -3.14) 168 self.assertEqual(float(".14 "), .14) 169 self.assertEqual(float("3. "), 3.0) 170 self.assertEqual(float("3.e3 "), 3000.0) 171 self.assertEqual(float("3.2e3 "), 3200.0) 172 self.assertEqual(float("2.5e-1 "), 0.25) 173 self.assertEqual(float("5e-1"), 0.5) 174 self.assertRaises(ValueError, float, " 3,14 ") 175 self.assertRaises(ValueError, float, " +3,14 ") 176 self.assertRaises(ValueError, float, " -3,14 ") 177 self.assertRaises(ValueError, float, " 0x3.1 ") 178 self.assertRaises(ValueError, float, " -0x3.p-1 ") 179 self.assertRaises(ValueError, float, " +0x3.p-1 ") 180 self.assertEqual(float(" 25.e-1 "), 2.5) 181 self.assertAlmostEqual(float(" .25e-1 "), .025) 182 183 def test_floatconversion(self): 184 # Make sure that calls to __float__() work properly 185 class Foo1(object): 186 def __float__(self): 187 return 42. 188 189 class Foo2(float): 190 def __float__(self): 191 return 42. 192 193 class Foo3(float): 194 def __new__(cls, value=0.): 195 return float.__new__(cls, 2*value) 196 197 def __float__(self): 198 return self 199 200 class Foo4(float): 201 def __float__(self): 202 return 42 203 204 # Issue 5759: __float__ not called on str subclasses (though it is on 205 # unicode subclasses). 206 class FooStr(str): 207 def __float__(self): 208 return float(str(self)) + 1 209 210 self.assertEqual(float(Foo1()), 42.) 211 self.assertEqual(float(Foo2()), 42.) 212 with self.assertWarns(DeprecationWarning): 213 self.assertEqual(float(Foo3(21)), 42.) 214 self.assertRaises(TypeError, float, Foo4(42)) 215 self.assertEqual(float(FooStr('8')), 9.) 216 217 class Foo5: 218 def __float__(self): 219 return "" 220 self.assertRaises(TypeError, time.sleep, Foo5()) 221 222 # Issue #24731 223 class F: 224 def __float__(self): 225 return OtherFloatSubclass(42.) 226 with self.assertWarns(DeprecationWarning): 227 self.assertEqual(float(F()), 42.) 228 with self.assertWarns(DeprecationWarning): 229 self.assertIs(type(float(F())), float) 230 with self.assertWarns(DeprecationWarning): 231 self.assertEqual(FloatSubclass(F()), 42.) 232 with self.assertWarns(DeprecationWarning): 233 self.assertIs(type(FloatSubclass(F())), FloatSubclass) 234 235 class MyIndex: 236 def __init__(self, value): 237 self.value = value 238 def __index__(self): 239 return self.value 240 241 self.assertEqual(float(MyIndex(42)), 42.0) 242 self.assertRaises(OverflowError, float, MyIndex(2**2000)) 243 244 class MyInt: 245 def __int__(self): 246 return 42 247 248 self.assertRaises(TypeError, float, MyInt()) 249 250 def test_keyword_args(self): 251 with self.assertRaisesRegex(TypeError, 'keyword argument'): 252 float(x='3.14') 253 254 def test_keywords_in_subclass(self): 255 class subclass(float): 256 pass 257 u = subclass(2.5) 258 self.assertIs(type(u), subclass) 259 self.assertEqual(float(u), 2.5) 260 with self.assertRaises(TypeError): 261 subclass(x=0) 262 263 class subclass_with_init(float): 264 def __init__(self, arg, newarg=None): 265 self.newarg = newarg 266 u = subclass_with_init(2.5, newarg=3) 267 self.assertIs(type(u), subclass_with_init) 268 self.assertEqual(float(u), 2.5) 269 self.assertEqual(u.newarg, 3) 270 271 class subclass_with_new(float): 272 def __new__(cls, arg, newarg=None): 273 self = super().__new__(cls, arg) 274 self.newarg = newarg 275 return self 276 u = subclass_with_new(2.5, newarg=3) 277 self.assertIs(type(u), subclass_with_new) 278 self.assertEqual(float(u), 2.5) 279 self.assertEqual(u.newarg, 3) 280 281 def test_is_integer(self): 282 self.assertFalse((1.1).is_integer()) 283 self.assertTrue((1.).is_integer()) 284 self.assertFalse(float("nan").is_integer()) 285 self.assertFalse(float("inf").is_integer()) 286 287 def test_floatasratio(self): 288 for f, ratio in [ 289 (0.875, (7, 8)), 290 (-0.875, (-7, 8)), 291 (0.0, (0, 1)), 292 (11.5, (23, 2)), 293 ]: 294 self.assertEqual(f.as_integer_ratio(), ratio) 295 296 for i in range(10000): 297 f = random.random() 298 f *= 10 ** random.randint(-100, 100) 299 n, d = f.as_integer_ratio() 300 self.assertEqual(float(n).__truediv__(d), f) 301 302 R = fractions.Fraction 303 self.assertEqual(R(0, 1), 304 R(*float(0.0).as_integer_ratio())) 305 self.assertEqual(R(5, 2), 306 R(*float(2.5).as_integer_ratio())) 307 self.assertEqual(R(1, 2), 308 R(*float(0.5).as_integer_ratio())) 309 self.assertEqual(R(4728779608739021, 2251799813685248), 310 R(*float(2.1).as_integer_ratio())) 311 self.assertEqual(R(-4728779608739021, 2251799813685248), 312 R(*float(-2.1).as_integer_ratio())) 313 self.assertEqual(R(-2100, 1), 314 R(*float(-2100.0).as_integer_ratio())) 315 316 self.assertRaises(OverflowError, float('inf').as_integer_ratio) 317 self.assertRaises(OverflowError, float('-inf').as_integer_ratio) 318 self.assertRaises(ValueError, float('nan').as_integer_ratio) 319 320 def test_float_containment(self): 321 floats = (INF, -INF, 0.0, 1.0, NAN) 322 for f in floats: 323 self.assertIn(f, [f]) 324 self.assertIn(f, (f,)) 325 self.assertIn(f, {f}) 326 self.assertIn(f, {f: None}) 327 self.assertEqual([f].count(f), 1, "[].count('%r') != 1" % f) 328 self.assertIn(f, floats) 329 330 for f in floats: 331 # nonidentical containers, same type, same contents 332 self.assertTrue([f] == [f], "[%r] != [%r]" % (f, f)) 333 self.assertTrue((f,) == (f,), "(%r,) != (%r,)" % (f, f)) 334 self.assertTrue({f} == {f}, "{%r} != {%r}" % (f, f)) 335 self.assertTrue({f : None} == {f: None}, "{%r : None} != " 336 "{%r : None}" % (f, f)) 337 338 # identical containers 339 l, t, s, d = [f], (f,), {f}, {f: None} 340 self.assertTrue(l == l, "[%r] not equal to itself" % f) 341 self.assertTrue(t == t, "(%r,) not equal to itself" % f) 342 self.assertTrue(s == s, "{%r} not equal to itself" % f) 343 self.assertTrue(d == d, "{%r : None} not equal to itself" % f) 344 345 def assertEqualAndEqualSign(self, a, b): 346 # fail unless a == b and a and b have the same sign bit; 347 # the only difference from assertEqual is that this test 348 # distinguishes -0.0 and 0.0. 349 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b))) 350 351 def test_float_floor(self): 352 self.assertIsInstance(float(0.5).__floor__(), int) 353 self.assertEqual(float(0.5).__floor__(), 0) 354 self.assertEqual(float(1.0).__floor__(), 1) 355 self.assertEqual(float(1.5).__floor__(), 1) 356 self.assertEqual(float(-0.5).__floor__(), -1) 357 self.assertEqual(float(-1.0).__floor__(), -1) 358 self.assertEqual(float(-1.5).__floor__(), -2) 359 self.assertEqual(float(1.23e167).__floor__(), 1.23e167) 360 self.assertEqual(float(-1.23e167).__floor__(), -1.23e167) 361 self.assertRaises(ValueError, float("nan").__floor__) 362 self.assertRaises(OverflowError, float("inf").__floor__) 363 self.assertRaises(OverflowError, float("-inf").__floor__) 364 365 def test_float_ceil(self): 366 self.assertIsInstance(float(0.5).__ceil__(), int) 367 self.assertEqual(float(0.5).__ceil__(), 1) 368 self.assertEqual(float(1.0).__ceil__(), 1) 369 self.assertEqual(float(1.5).__ceil__(), 2) 370 self.assertEqual(float(-0.5).__ceil__(), 0) 371 self.assertEqual(float(-1.0).__ceil__(), -1) 372 self.assertEqual(float(-1.5).__ceil__(), -1) 373 self.assertEqual(float(1.23e167).__ceil__(), 1.23e167) 374 self.assertEqual(float(-1.23e167).__ceil__(), -1.23e167) 375 self.assertRaises(ValueError, float("nan").__ceil__) 376 self.assertRaises(OverflowError, float("inf").__ceil__) 377 self.assertRaises(OverflowError, float("-inf").__ceil__) 378 379 @support.requires_IEEE_754 380 def test_float_mod(self): 381 # Check behaviour of % operator for IEEE 754 special cases. 382 # In particular, check signs of zeros. 383 mod = operator.mod 384 385 self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0) 386 self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0) 387 self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0) 388 self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0) 389 self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100) 390 self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0) 391 392 self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0) 393 self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100) 394 self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0) 395 self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0) 396 self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0) 397 self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0) 398 399 @support.requires_IEEE_754 400 def test_float_pow(self): 401 # test builtin pow and ** operator for IEEE 754 special cases. 402 # Special cases taken from section F.9.4.4 of the C99 specification 403 404 for pow_op in pow, operator.pow: 405 # x**NAN is NAN for any x except 1 406 self.assertTrue(isnan(pow_op(-INF, NAN))) 407 self.assertTrue(isnan(pow_op(-2.0, NAN))) 408 self.assertTrue(isnan(pow_op(-1.0, NAN))) 409 self.assertTrue(isnan(pow_op(-0.5, NAN))) 410 self.assertTrue(isnan(pow_op(-0.0, NAN))) 411 self.assertTrue(isnan(pow_op(0.0, NAN))) 412 self.assertTrue(isnan(pow_op(0.5, NAN))) 413 self.assertTrue(isnan(pow_op(2.0, NAN))) 414 self.assertTrue(isnan(pow_op(INF, NAN))) 415 self.assertTrue(isnan(pow_op(NAN, NAN))) 416 417 # NAN**y is NAN for any y except +-0 418 self.assertTrue(isnan(pow_op(NAN, -INF))) 419 self.assertTrue(isnan(pow_op(NAN, -2.0))) 420 self.assertTrue(isnan(pow_op(NAN, -1.0))) 421 self.assertTrue(isnan(pow_op(NAN, -0.5))) 422 self.assertTrue(isnan(pow_op(NAN, 0.5))) 423 self.assertTrue(isnan(pow_op(NAN, 1.0))) 424 self.assertTrue(isnan(pow_op(NAN, 2.0))) 425 self.assertTrue(isnan(pow_op(NAN, INF))) 426 427 # (+-0)**y raises ZeroDivisionError for y a negative odd integer 428 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0) 429 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0) 430 431 # (+-0)**y raises ZeroDivisionError for y finite and negative 432 # but not an odd integer 433 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0) 434 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5) 435 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0) 436 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5) 437 438 # (+-0)**y is +-0 for y a positive odd integer 439 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0) 440 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0) 441 442 # (+-0)**y is 0 for y finite and positive but not an odd integer 443 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0) 444 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0) 445 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0) 446 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0) 447 448 # (-1)**+-inf is 1 449 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0) 450 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0) 451 452 # 1**y is 1 for any y, even if y is an infinity or nan 453 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0) 454 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0) 455 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0) 456 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0) 457 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0) 458 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0) 459 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0) 460 self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0) 461 self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0) 462 self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0) 463 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0) 464 465 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan 466 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0) 467 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0) 468 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0) 469 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0) 470 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0) 471 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0) 472 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0) 473 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0) 474 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0) 475 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0) 476 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0) 477 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0) 478 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0) 479 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0) 480 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0) 481 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0) 482 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0) 483 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0) 484 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0) 485 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0) 486 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0) 487 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0) 488 489 # x**y defers to complex pow for finite negative x and 490 # non-integral y. 491 self.assertEqual(type(pow_op(-2.0, -0.5)), complex) 492 self.assertEqual(type(pow_op(-2.0, 0.5)), complex) 493 self.assertEqual(type(pow_op(-1.0, -0.5)), complex) 494 self.assertEqual(type(pow_op(-1.0, 0.5)), complex) 495 self.assertEqual(type(pow_op(-0.5, -0.5)), complex) 496 self.assertEqual(type(pow_op(-0.5, 0.5)), complex) 497 498 # x**-INF is INF for abs(x) < 1 499 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF) 500 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF) 501 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF) 502 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF) 503 504 # x**-INF is 0 for abs(x) > 1 505 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0) 506 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0) 507 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0) 508 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0) 509 510 # x**INF is 0 for abs(x) < 1 511 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0) 512 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0) 513 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0) 514 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0) 515 516 # x**INF is INF for abs(x) > 1 517 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF) 518 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF) 519 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF) 520 self.assertEqualAndEqualSign(pow_op(INF, INF), INF) 521 522 # (-INF)**y is -0.0 for y a negative odd integer 523 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0) 524 525 # (-INF)**y is 0.0 for y negative but not an odd integer 526 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0) 527 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0) 528 529 # (-INF)**y is -INF for y a positive odd integer 530 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF) 531 532 # (-INF)**y is INF for y positive but not an odd integer 533 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF) 534 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF) 535 536 # INF**y is INF for y positive 537 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF) 538 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF) 539 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF) 540 541 # INF**y is 0.0 for y negative 542 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0) 543 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0) 544 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0) 545 546 # basic checks not covered by the special cases above 547 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25) 548 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5) 549 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0) 550 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0) 551 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0) 552 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0) 553 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0) 554 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0) 555 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0) 556 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0) 557 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0) 558 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0) 559 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25) 560 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5) 561 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0) 562 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0) 563 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0) 564 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0) 565 566 # 1 ** large and -1 ** large; some libms apparently 567 # have problems with these 568 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0) 569 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0) 570 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0) 571 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0) 572 573 # check sign for results that underflow to 0 574 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0) 575 self.assertEqual(type(pow_op(-2.0, -2000.5)), complex) 576 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0) 577 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0) 578 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0) 579 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0) 580 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0) 581 self.assertEqual(type(pow_op(-0.5, 2000.5)), complex) 582 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0) 583 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0) 584 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0) 585 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0) 586 587 # check we don't raise an exception for subnormal results, 588 # and validate signs. Tests currently disabled, since 589 # they fail on systems where a subnormal result from pow 590 # is flushed to zero (e.g. Debian/ia64.) 591 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315) 592 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315) 593 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315) 594 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315) 595 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315) 596 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315) 597 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315) 598 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315) 599 600 def test_hash(self): 601 for x in range(-30, 30): 602 self.assertEqual(hash(float(x)), hash(x)) 603 self.assertEqual(hash(float(sys.float_info.max)), 604 hash(int(sys.float_info.max))) 605 self.assertEqual(hash(float('inf')), sys.hash_info.inf) 606 self.assertEqual(hash(float('-inf')), -sys.hash_info.inf) 607 608 def test_hash_nan(self): 609 value = float('nan') 610 self.assertEqual(hash(value), object.__hash__(value)) 611 class H: 612 def __hash__(self): 613 return 42 614 class F(float, H): 615 pass 616 value = F('nan') 617 self.assertEqual(hash(value), object.__hash__(value)) 618 619 620@unittest.skipUnless(hasattr(float, "__getformat__"), "requires __getformat__") 621class FormatFunctionsTestCase(unittest.TestCase): 622 def test_getformat(self): 623 self.assertIn(float.__getformat__('double'), 624 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian']) 625 self.assertIn(float.__getformat__('float'), 626 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian']) 627 self.assertRaises(ValueError, float.__getformat__, 'chicken') 628 self.assertRaises(TypeError, float.__getformat__, 1) 629 630 631BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00' 632LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF)) 633BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00' 634LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN)) 635 636BE_FLOAT_INF = b'\x7f\x80\x00\x00' 637LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF)) 638BE_FLOAT_NAN = b'\x7f\xc0\x00\x00' 639LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN)) 640 641# on an IEEE platform, all we guarantee is that bit patterns 642# representing infinities or NaNs do not raise an exception; all else 643# is accident (today). 644# let's also try to guarantee that -0.0 and 0.0 don't get confused. 645 646class IEEEFormatTestCase(unittest.TestCase): 647 648 @support.requires_IEEE_754 649 def test_double_specials_do_unpack(self): 650 for fmt, data in [('>d', BE_DOUBLE_INF), 651 ('>d', BE_DOUBLE_NAN), 652 ('<d', LE_DOUBLE_INF), 653 ('<d', LE_DOUBLE_NAN)]: 654 struct.unpack(fmt, data) 655 656 @support.requires_IEEE_754 657 def test_float_specials_do_unpack(self): 658 for fmt, data in [('>f', BE_FLOAT_INF), 659 ('>f', BE_FLOAT_NAN), 660 ('<f', LE_FLOAT_INF), 661 ('<f', LE_FLOAT_NAN)]: 662 struct.unpack(fmt, data) 663 664 @support.requires_IEEE_754 665 @unittest.skipIf(_testcapi is None, 'needs _testcapi') 666 def test_serialized_float_rounding(self): 667 FLT_MAX = _testcapi.FLT_MAX 668 self.assertEqual(struct.pack("<f", 3.40282356e38), struct.pack("<f", FLT_MAX)) 669 self.assertEqual(struct.pack("<f", -3.40282356e38), struct.pack("<f", -FLT_MAX)) 670 671class FormatTestCase(unittest.TestCase): 672 673 def test_format(self): 674 # these should be rewritten to use both format(x, spec) and 675 # x.__format__(spec) 676 677 self.assertEqual(format(0.0, 'f'), '0.000000') 678 679 # the default is 'g', except for empty format spec 680 self.assertEqual(format(0.0, ''), '0.0') 681 self.assertEqual(format(0.01, ''), '0.01') 682 self.assertEqual(format(0.01, 'g'), '0.01') 683 684 # empty presentation type should format in the same way as str 685 # (issue 5920) 686 x = 100/7. 687 self.assertEqual(format(x, ''), str(x)) 688 self.assertEqual(format(x, '-'), str(x)) 689 self.assertEqual(format(x, '>'), str(x)) 690 self.assertEqual(format(x, '2'), str(x)) 691 692 self.assertEqual(format(1.0, 'f'), '1.000000') 693 694 self.assertEqual(format(-1.0, 'f'), '-1.000000') 695 696 self.assertEqual(format( 1.0, ' f'), ' 1.000000') 697 self.assertEqual(format(-1.0, ' f'), '-1.000000') 698 self.assertEqual(format( 1.0, '+f'), '+1.000000') 699 self.assertEqual(format(-1.0, '+f'), '-1.000000') 700 701 # % formatting 702 self.assertEqual(format(-1.0, '%'), '-100.000000%') 703 704 # conversion to string should fail 705 self.assertRaises(ValueError, format, 3.0, "s") 706 707 # confirm format options expected to fail on floats, such as integer 708 # presentation types 709 for format_spec in 'sbcdoxX': 710 self.assertRaises(ValueError, format, 0.0, format_spec) 711 self.assertRaises(ValueError, format, 1.0, format_spec) 712 self.assertRaises(ValueError, format, -1.0, format_spec) 713 self.assertRaises(ValueError, format, 1e100, format_spec) 714 self.assertRaises(ValueError, format, -1e100, format_spec) 715 self.assertRaises(ValueError, format, 1e-100, format_spec) 716 self.assertRaises(ValueError, format, -1e-100, format_spec) 717 718 # issue 3382 719 self.assertEqual(format(NAN, 'f'), 'nan') 720 self.assertEqual(format(NAN, 'F'), 'NAN') 721 self.assertEqual(format(INF, 'f'), 'inf') 722 self.assertEqual(format(INF, 'F'), 'INF') 723 724 @support.requires_IEEE_754 725 def test_format_testfile(self): 726 with open(format_testfile, encoding="utf-8") as testfile: 727 for line in testfile: 728 if line.startswith('--'): 729 continue 730 line = line.strip() 731 if not line: 732 continue 733 734 lhs, rhs = map(str.strip, line.split('->')) 735 fmt, arg = lhs.split() 736 f = float(arg) 737 self.assertEqual(fmt % f, rhs) 738 self.assertEqual(fmt % -f, '-' + rhs) 739 if fmt != '%r': 740 fmt2 = fmt[1:] 741 self.assertEqual(format(f, fmt2), rhs) 742 self.assertEqual(format(-f, fmt2), '-' + rhs) 743 744 def test_issue5864(self): 745 self.assertEqual(format(123.456, '.4'), '123.5') 746 self.assertEqual(format(1234.56, '.4'), '1.235e+03') 747 self.assertEqual(format(12345.6, '.4'), '1.235e+04') 748 749 def test_issue35560(self): 750 self.assertEqual(format(123.0, '00'), '123.0') 751 self.assertEqual(format(123.34, '00f'), '123.340000') 752 self.assertEqual(format(123.34, '00e'), '1.233400e+02') 753 self.assertEqual(format(123.34, '00g'), '123.34') 754 self.assertEqual(format(123.34, '00.10f'), '123.3400000000') 755 self.assertEqual(format(123.34, '00.10e'), '1.2334000000e+02') 756 self.assertEqual(format(123.34, '00.10g'), '123.34') 757 self.assertEqual(format(123.34, '01f'), '123.340000') 758 759 self.assertEqual(format(-123.0, '00'), '-123.0') 760 self.assertEqual(format(-123.34, '00f'), '-123.340000') 761 self.assertEqual(format(-123.34, '00e'), '-1.233400e+02') 762 self.assertEqual(format(-123.34, '00g'), '-123.34') 763 self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000') 764 self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000') 765 self.assertEqual(format(-123.34, '00.10e'), '-1.2334000000e+02') 766 self.assertEqual(format(-123.34, '00.10g'), '-123.34') 767 768class ReprTestCase(unittest.TestCase): 769 def test_repr(self): 770 with open(os.path.join(os.path.split(__file__)[0], 771 'mathdata', 772 'floating_points.txt'), encoding="utf-8") as floats_file: 773 for line in floats_file: 774 line = line.strip() 775 if not line or line.startswith('#'): 776 continue 777 v = eval(line) 778 self.assertEqual(v, eval(repr(v))) 779 780 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', 781 "applies only when using short float repr style") 782 def test_short_repr(self): 783 # test short float repr introduced in Python 3.1. One aspect 784 # of this repr is that we get some degree of str -> float -> 785 # str roundtripping. In particular, for any numeric string 786 # containing 15 or fewer significant digits, those exact same 787 # digits (modulo trailing zeros) should appear in the output. 788 # No more repr(0.03) -> "0.029999999999999999"! 789 790 test_strings = [ 791 # output always includes *either* a decimal point and at 792 # least one digit after that point, or an exponent. 793 '0.0', 794 '1.0', 795 '0.01', 796 '0.02', 797 '0.03', 798 '0.04', 799 '0.05', 800 '1.23456789', 801 '10.0', 802 '100.0', 803 # values >= 1e16 get an exponent... 804 '1000000000000000.0', 805 '9999999999999990.0', 806 '1e+16', 807 '1e+17', 808 # ... and so do values < 1e-4 809 '0.001', 810 '0.001001', 811 '0.00010000000000001', 812 '0.0001', 813 '9.999999999999e-05', 814 '1e-05', 815 # values designed to provoke failure if the FPU rounding 816 # precision isn't set correctly 817 '8.72293771110361e+25', 818 '7.47005307342313e+26', 819 '2.86438000439698e+28', 820 '8.89142905246179e+28', 821 '3.08578087079232e+35', 822 ] 823 824 for s in test_strings: 825 negs = '-'+s 826 self.assertEqual(s, repr(float(s))) 827 self.assertEqual(negs, repr(float(negs))) 828 # Since Python 3.2, repr and str are identical 829 self.assertEqual(repr(float(s)), str(float(s))) 830 self.assertEqual(repr(float(negs)), str(float(negs))) 831 832@support.requires_IEEE_754 833class RoundTestCase(unittest.TestCase, FloatsAreIdenticalMixin): 834 835 def test_inf_nan(self): 836 self.assertRaises(OverflowError, round, INF) 837 self.assertRaises(OverflowError, round, -INF) 838 self.assertRaises(ValueError, round, NAN) 839 self.assertRaises(TypeError, round, INF, 0.0) 840 self.assertRaises(TypeError, round, -INF, 1.0) 841 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer") 842 self.assertRaises(TypeError, round, -0.0, 1j) 843 844 def test_inf_nan_ndigits(self): 845 self.assertEqual(round(INF, 0), INF) 846 self.assertEqual(round(-INF, 0), -INF) 847 self.assertTrue(math.isnan(round(NAN, 0))) 848 849 def test_large_n(self): 850 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]: 851 self.assertEqual(round(123.456, n), 123.456) 852 self.assertEqual(round(-123.456, n), -123.456) 853 self.assertEqual(round(1e300, n), 1e300) 854 self.assertEqual(round(1e-320, n), 1e-320) 855 self.assertEqual(round(1e150, 300), 1e150) 856 self.assertEqual(round(1e300, 307), 1e300) 857 self.assertEqual(round(-3.1415, 308), -3.1415) 858 self.assertEqual(round(1e150, 309), 1e150) 859 self.assertEqual(round(1.4e-315, 315), 1e-315) 860 861 def test_small_n(self): 862 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]: 863 self.assertFloatsAreIdentical(round(123.456, n), 0.0) 864 self.assertFloatsAreIdentical(round(-123.456, n), -0.0) 865 self.assertFloatsAreIdentical(round(1e300, n), 0.0) 866 self.assertFloatsAreIdentical(round(1e-320, n), 0.0) 867 868 def test_overflow(self): 869 self.assertRaises(OverflowError, round, 1.6e308, -308) 870 self.assertRaises(OverflowError, round, -1.7e308, -308) 871 872 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', 873 "applies only when using short float repr style") 874 def test_previous_round_bugs(self): 875 # particular cases that have occurred in bug reports 876 self.assertEqual(round(562949953421312.5, 1), 877 562949953421312.5) 878 self.assertEqual(round(56294995342131.5, 3), 879 56294995342131.5) 880 # round-half-even 881 self.assertEqual(round(25.0, -1), 20.0) 882 self.assertEqual(round(35.0, -1), 40.0) 883 self.assertEqual(round(45.0, -1), 40.0) 884 self.assertEqual(round(55.0, -1), 60.0) 885 self.assertEqual(round(65.0, -1), 60.0) 886 self.assertEqual(round(75.0, -1), 80.0) 887 self.assertEqual(round(85.0, -1), 80.0) 888 self.assertEqual(round(95.0, -1), 100.0) 889 890 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', 891 "applies only when using short float repr style") 892 def test_matches_float_format(self): 893 # round should give the same results as float formatting 894 for i in range(500): 895 x = i/1000. 896 self.assertEqual(float(format(x, '.0f')), round(x, 0)) 897 self.assertEqual(float(format(x, '.1f')), round(x, 1)) 898 self.assertEqual(float(format(x, '.2f')), round(x, 2)) 899 self.assertEqual(float(format(x, '.3f')), round(x, 3)) 900 901 for i in range(5, 5000, 10): 902 x = i/1000. 903 self.assertEqual(float(format(x, '.0f')), round(x, 0)) 904 self.assertEqual(float(format(x, '.1f')), round(x, 1)) 905 self.assertEqual(float(format(x, '.2f')), round(x, 2)) 906 self.assertEqual(float(format(x, '.3f')), round(x, 3)) 907 908 for i in range(500): 909 x = random.random() 910 self.assertEqual(float(format(x, '.0f')), round(x, 0)) 911 self.assertEqual(float(format(x, '.1f')), round(x, 1)) 912 self.assertEqual(float(format(x, '.2f')), round(x, 2)) 913 self.assertEqual(float(format(x, '.3f')), round(x, 3)) 914 915 def test_format_specials(self): 916 # Test formatting of nans and infs. 917 918 def test(fmt, value, expected): 919 # Test with both % and format(). 920 self.assertEqual(fmt % value, expected, fmt) 921 fmt = fmt[1:] # strip off the % 922 self.assertEqual(format(value, fmt), expected, fmt) 923 924 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g', 925 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']: 926 pfmt = '%+' + fmt[1:] 927 sfmt = '% ' + fmt[1:] 928 test(fmt, INF, 'inf') 929 test(fmt, -INF, '-inf') 930 test(fmt, NAN, 'nan') 931 test(fmt, -NAN, 'nan') 932 # When asking for a sign, it's always provided. nans are 933 # always positive. 934 test(pfmt, INF, '+inf') 935 test(pfmt, -INF, '-inf') 936 test(pfmt, NAN, '+nan') 937 test(pfmt, -NAN, '+nan') 938 # When using ' ' for a sign code, only infs can be negative. 939 # Others have a space. 940 test(sfmt, INF, ' inf') 941 test(sfmt, -INF, '-inf') 942 test(sfmt, NAN, ' nan') 943 test(sfmt, -NAN, ' nan') 944 945 def test_None_ndigits(self): 946 for x in round(1.23), round(1.23, None), round(1.23, ndigits=None): 947 self.assertEqual(x, 1) 948 self.assertIsInstance(x, int) 949 for x in round(1.78), round(1.78, None), round(1.78, ndigits=None): 950 self.assertEqual(x, 2) 951 self.assertIsInstance(x, int) 952 953 954# Beginning with Python 2.6 float has cross platform compatible 955# ways to create and represent inf and nan 956class InfNanTest(unittest.TestCase): 957 def test_inf_from_str(self): 958 self.assertTrue(isinf(float("inf"))) 959 self.assertTrue(isinf(float("+inf"))) 960 self.assertTrue(isinf(float("-inf"))) 961 self.assertTrue(isinf(float("infinity"))) 962 self.assertTrue(isinf(float("+infinity"))) 963 self.assertTrue(isinf(float("-infinity"))) 964 965 self.assertEqual(repr(float("inf")), "inf") 966 self.assertEqual(repr(float("+inf")), "inf") 967 self.assertEqual(repr(float("-inf")), "-inf") 968 self.assertEqual(repr(float("infinity")), "inf") 969 self.assertEqual(repr(float("+infinity")), "inf") 970 self.assertEqual(repr(float("-infinity")), "-inf") 971 972 self.assertEqual(repr(float("INF")), "inf") 973 self.assertEqual(repr(float("+Inf")), "inf") 974 self.assertEqual(repr(float("-iNF")), "-inf") 975 self.assertEqual(repr(float("Infinity")), "inf") 976 self.assertEqual(repr(float("+iNfInItY")), "inf") 977 self.assertEqual(repr(float("-INFINITY")), "-inf") 978 979 self.assertEqual(str(float("inf")), "inf") 980 self.assertEqual(str(float("+inf")), "inf") 981 self.assertEqual(str(float("-inf")), "-inf") 982 self.assertEqual(str(float("infinity")), "inf") 983 self.assertEqual(str(float("+infinity")), "inf") 984 self.assertEqual(str(float("-infinity")), "-inf") 985 986 self.assertRaises(ValueError, float, "info") 987 self.assertRaises(ValueError, float, "+info") 988 self.assertRaises(ValueError, float, "-info") 989 self.assertRaises(ValueError, float, "in") 990 self.assertRaises(ValueError, float, "+in") 991 self.assertRaises(ValueError, float, "-in") 992 self.assertRaises(ValueError, float, "infinit") 993 self.assertRaises(ValueError, float, "+Infin") 994 self.assertRaises(ValueError, float, "-INFI") 995 self.assertRaises(ValueError, float, "infinitys") 996 997 self.assertRaises(ValueError, float, "++Inf") 998 self.assertRaises(ValueError, float, "-+inf") 999 self.assertRaises(ValueError, float, "+-infinity") 1000 self.assertRaises(ValueError, float, "--Infinity") 1001 1002 def test_inf_as_str(self): 1003 self.assertEqual(repr(1e300 * 1e300), "inf") 1004 self.assertEqual(repr(-1e300 * 1e300), "-inf") 1005 1006 self.assertEqual(str(1e300 * 1e300), "inf") 1007 self.assertEqual(str(-1e300 * 1e300), "-inf") 1008 1009 def test_nan_from_str(self): 1010 self.assertTrue(isnan(float("nan"))) 1011 self.assertTrue(isnan(float("+nan"))) 1012 self.assertTrue(isnan(float("-nan"))) 1013 1014 self.assertEqual(repr(float("nan")), "nan") 1015 self.assertEqual(repr(float("+nan")), "nan") 1016 self.assertEqual(repr(float("-nan")), "nan") 1017 1018 self.assertEqual(repr(float("NAN")), "nan") 1019 self.assertEqual(repr(float("+NAn")), "nan") 1020 self.assertEqual(repr(float("-NaN")), "nan") 1021 1022 self.assertEqual(str(float("nan")), "nan") 1023 self.assertEqual(str(float("+nan")), "nan") 1024 self.assertEqual(str(float("-nan")), "nan") 1025 1026 self.assertRaises(ValueError, float, "nana") 1027 self.assertRaises(ValueError, float, "+nana") 1028 self.assertRaises(ValueError, float, "-nana") 1029 self.assertRaises(ValueError, float, "na") 1030 self.assertRaises(ValueError, float, "+na") 1031 self.assertRaises(ValueError, float, "-na") 1032 1033 self.assertRaises(ValueError, float, "++nan") 1034 self.assertRaises(ValueError, float, "-+NAN") 1035 self.assertRaises(ValueError, float, "+-NaN") 1036 self.assertRaises(ValueError, float, "--nAn") 1037 1038 def test_nan_as_str(self): 1039 self.assertEqual(repr(1e300 * 1e300 * 0), "nan") 1040 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan") 1041 1042 self.assertEqual(str(1e300 * 1e300 * 0), "nan") 1043 self.assertEqual(str(-1e300 * 1e300 * 0), "nan") 1044 1045 def test_inf_signs(self): 1046 self.assertEqual(copysign(1.0, float('inf')), 1.0) 1047 self.assertEqual(copysign(1.0, float('-inf')), -1.0) 1048 1049 def test_nan_signs(self): 1050 # The sign of float('nan') should be predictable. 1051 self.assertEqual(copysign(1.0, float('nan')), 1.0) 1052 self.assertEqual(copysign(1.0, float('-nan')), -1.0) 1053 1054 1055fromHex = float.fromhex 1056toHex = float.hex 1057class HexFloatTestCase(FloatsAreIdenticalMixin, unittest.TestCase): 1058 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal 1059 MIN = fromHex('0x1p-1022') # min normal 1060 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal 1061 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up 1062 1063 def identical(self, x, y): 1064 self.assertFloatsAreIdentical(x, y) 1065 1066 def test_ends(self): 1067 self.identical(self.MIN, ldexp(1.0, -1022)) 1068 self.identical(self.TINY, ldexp(1.0, -1074)) 1069 self.identical(self.EPS, ldexp(1.0, -52)) 1070 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970))) 1071 1072 def test_invalid_inputs(self): 1073 invalid_inputs = [ 1074 'infi', # misspelt infinities and nans 1075 '-Infinit', 1076 '++inf', 1077 '-+Inf', 1078 '--nan', 1079 '+-NaN', 1080 'snan', 1081 'NaNs', 1082 'nna', 1083 'an', 1084 'nf', 1085 'nfinity', 1086 'inity', 1087 'iinity', 1088 '0xnan', 1089 '', 1090 ' ', 1091 'x1.0p0', 1092 '0xX1.0p0', 1093 '+ 0x1.0p0', # internal whitespace 1094 '- 0x1.0p0', 1095 '0 x1.0p0', 1096 '0x 1.0p0', 1097 '0x1 2.0p0', 1098 '+0x1 .0p0', 1099 '0x1. 0p0', 1100 '-0x1.0 1p0', 1101 '-0x1.0 p0', 1102 '+0x1.0p +0', 1103 '0x1.0p -0', 1104 '0x1.0p 0', 1105 '+0x1.0p+ 0', 1106 '-0x1.0p- 0', 1107 '++0x1.0p-0', # double signs 1108 '--0x1.0p0', 1109 '+-0x1.0p+0', 1110 '-+0x1.0p0', 1111 '0x1.0p++0', 1112 '+0x1.0p+-0', 1113 '-0x1.0p-+0', 1114 '0x1.0p--0', 1115 '0x1.0.p0', 1116 '0x.p0', # no hex digits before or after point 1117 '0x1,p0', # wrong decimal point character 1118 '0x1pa', 1119 '0x1p\uff10', # fullwidth Unicode digits 1120 '\uff10x1p0', 1121 '0x\uff11p0', 1122 '0x1.\uff10p0', 1123 '0x1p0 \n 0x2p0', 1124 '0x1p0\0 0x1p0', # embedded null byte is not end of string 1125 ] 1126 for x in invalid_inputs: 1127 try: 1128 result = fromHex(x) 1129 except ValueError: 1130 pass 1131 else: 1132 self.fail('Expected float.fromhex(%r) to raise ValueError; ' 1133 'got %r instead' % (x, result)) 1134 1135 1136 def test_whitespace(self): 1137 value_pairs = [ 1138 ('inf', INF), 1139 ('-Infinity', -INF), 1140 ('nan', NAN), 1141 ('1.0', 1.0), 1142 ('-0x.2', -0.125), 1143 ('-0.0', -0.0) 1144 ] 1145 whitespace = [ 1146 '', 1147 ' ', 1148 '\t', 1149 '\n', 1150 '\n \t', 1151 '\f', 1152 '\v', 1153 '\r' 1154 ] 1155 for inp, expected in value_pairs: 1156 for lead in whitespace: 1157 for trail in whitespace: 1158 got = fromHex(lead + inp + trail) 1159 self.identical(got, expected) 1160 1161 1162 def test_from_hex(self): 1163 MIN = self.MIN 1164 MAX = self.MAX 1165 TINY = self.TINY 1166 EPS = self.EPS 1167 1168 # two spellings of infinity, with optional signs; case-insensitive 1169 self.identical(fromHex('inf'), INF) 1170 self.identical(fromHex('+Inf'), INF) 1171 self.identical(fromHex('-INF'), -INF) 1172 self.identical(fromHex('iNf'), INF) 1173 self.identical(fromHex('Infinity'), INF) 1174 self.identical(fromHex('+INFINITY'), INF) 1175 self.identical(fromHex('-infinity'), -INF) 1176 self.identical(fromHex('-iNFiNitY'), -INF) 1177 1178 # nans with optional sign; case insensitive 1179 self.identical(fromHex('nan'), NAN) 1180 self.identical(fromHex('+NaN'), NAN) 1181 self.identical(fromHex('-NaN'), NAN) 1182 self.identical(fromHex('-nAN'), NAN) 1183 1184 # variations in input format 1185 self.identical(fromHex('1'), 1.0) 1186 self.identical(fromHex('+1'), 1.0) 1187 self.identical(fromHex('1.'), 1.0) 1188 self.identical(fromHex('1.0'), 1.0) 1189 self.identical(fromHex('1.0p0'), 1.0) 1190 self.identical(fromHex('01'), 1.0) 1191 self.identical(fromHex('01.'), 1.0) 1192 self.identical(fromHex('0x1'), 1.0) 1193 self.identical(fromHex('0x1.'), 1.0) 1194 self.identical(fromHex('0x1.0'), 1.0) 1195 self.identical(fromHex('+0x1.0'), 1.0) 1196 self.identical(fromHex('0x1p0'), 1.0) 1197 self.identical(fromHex('0X1p0'), 1.0) 1198 self.identical(fromHex('0X1P0'), 1.0) 1199 self.identical(fromHex('0x1P0'), 1.0) 1200 self.identical(fromHex('0x1.p0'), 1.0) 1201 self.identical(fromHex('0x1.0p0'), 1.0) 1202 self.identical(fromHex('0x.1p4'), 1.0) 1203 self.identical(fromHex('0x.1p04'), 1.0) 1204 self.identical(fromHex('0x.1p004'), 1.0) 1205 self.identical(fromHex('0x1p+0'), 1.0) 1206 self.identical(fromHex('0x1P-0'), 1.0) 1207 self.identical(fromHex('+0x1p0'), 1.0) 1208 self.identical(fromHex('0x01p0'), 1.0) 1209 self.identical(fromHex('0x1p00'), 1.0) 1210 self.identical(fromHex(' 0x1p0 '), 1.0) 1211 self.identical(fromHex('\n 0x1p0'), 1.0) 1212 self.identical(fromHex('0x1p0 \t'), 1.0) 1213 self.identical(fromHex('0xap0'), 10.0) 1214 self.identical(fromHex('0xAp0'), 10.0) 1215 self.identical(fromHex('0xaP0'), 10.0) 1216 self.identical(fromHex('0xAP0'), 10.0) 1217 self.identical(fromHex('0xbep0'), 190.0) 1218 self.identical(fromHex('0xBep0'), 190.0) 1219 self.identical(fromHex('0xbEp0'), 190.0) 1220 self.identical(fromHex('0XBE0P-4'), 190.0) 1221 self.identical(fromHex('0xBEp0'), 190.0) 1222 self.identical(fromHex('0xB.Ep4'), 190.0) 1223 self.identical(fromHex('0x.BEp8'), 190.0) 1224 self.identical(fromHex('0x.0BEp12'), 190.0) 1225 1226 # moving the point around 1227 pi = fromHex('0x1.921fb54442d18p1') 1228 self.identical(fromHex('0x.006487ed5110b46p11'), pi) 1229 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi) 1230 self.identical(fromHex('0x.01921fb54442d18p9'), pi) 1231 self.identical(fromHex('0x.03243f6a8885a3p8'), pi) 1232 self.identical(fromHex('0x.06487ed5110b46p7'), pi) 1233 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi) 1234 self.identical(fromHex('0x.1921fb54442d18p5'), pi) 1235 self.identical(fromHex('0x.3243f6a8885a3p4'), pi) 1236 self.identical(fromHex('0x.6487ed5110b46p3'), pi) 1237 self.identical(fromHex('0x.c90fdaa22168cp2'), pi) 1238 self.identical(fromHex('0x1.921fb54442d18p1'), pi) 1239 self.identical(fromHex('0x3.243f6a8885a3p0'), pi) 1240 self.identical(fromHex('0x6.487ed5110b46p-1'), pi) 1241 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi) 1242 self.identical(fromHex('0x19.21fb54442d18p-3'), pi) 1243 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi) 1244 self.identical(fromHex('0x64.87ed5110b46p-5'), pi) 1245 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi) 1246 self.identical(fromHex('0x192.1fb54442d18p-7'), pi) 1247 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi) 1248 self.identical(fromHex('0x648.7ed5110b46p-9'), pi) 1249 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi) 1250 self.identical(fromHex('0x1921.fb54442d18p-11'), pi) 1251 # ... 1252 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi) 1253 self.identical(fromHex('0x3243f6a8885a3p-48'), pi) 1254 self.identical(fromHex('0x6487ed5110b46p-49'), pi) 1255 self.identical(fromHex('0xc90fdaa22168cp-50'), pi) 1256 self.identical(fromHex('0x1921fb54442d18p-51'), pi) 1257 self.identical(fromHex('0x3243f6a8885a30p-52'), pi) 1258 self.identical(fromHex('0x6487ed5110b460p-53'), pi) 1259 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi) 1260 self.identical(fromHex('0x1921fb54442d180p-55'), pi) 1261 1262 1263 # results that should overflow... 1264 self.assertRaises(OverflowError, fromHex, '-0x1p1024') 1265 self.assertRaises(OverflowError, fromHex, '0x1p+1025') 1266 self.assertRaises(OverflowError, fromHex, '+0X1p1030') 1267 self.assertRaises(OverflowError, fromHex, '-0x1p+1100') 1268 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789') 1269 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025') 1270 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025') 1271 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026') 1272 self.assertRaises(OverflowError, fromHex, '0X2p+1023') 1273 self.assertRaises(OverflowError, fromHex, '0x2.p1023') 1274 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023') 1275 self.assertRaises(OverflowError, fromHex, '+0X4p+1022') 1276 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023') 1277 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023') 1278 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023') 1279 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022') 1280 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970') 1281 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960') 1282 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960') 1283 1284 # ...and those that round to +-max float 1285 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX) 1286 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX) 1287 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX) 1288 1289 # zeros 1290 self.identical(fromHex('0x0p0'), 0.0) 1291 self.identical(fromHex('0x0p1000'), 0.0) 1292 self.identical(fromHex('-0x0p1023'), -0.0) 1293 self.identical(fromHex('0X0p1024'), 0.0) 1294 self.identical(fromHex('-0x0p1025'), -0.0) 1295 self.identical(fromHex('0X0p2000'), 0.0) 1296 self.identical(fromHex('0x0p123456789123456789'), 0.0) 1297 self.identical(fromHex('-0X0p-0'), -0.0) 1298 self.identical(fromHex('-0X0p-1000'), -0.0) 1299 self.identical(fromHex('0x0p-1023'), 0.0) 1300 self.identical(fromHex('-0X0p-1024'), -0.0) 1301 self.identical(fromHex('-0x0p-1025'), -0.0) 1302 self.identical(fromHex('-0x0p-1072'), -0.0) 1303 self.identical(fromHex('0X0p-1073'), 0.0) 1304 self.identical(fromHex('-0x0p-1074'), -0.0) 1305 self.identical(fromHex('0x0p-1075'), 0.0) 1306 self.identical(fromHex('0X0p-1076'), 0.0) 1307 self.identical(fromHex('-0X0p-2000'), -0.0) 1308 self.identical(fromHex('-0x0p-123456789123456789'), -0.0) 1309 1310 # values that should underflow to 0 1311 self.identical(fromHex('0X1p-1075'), 0.0) 1312 self.identical(fromHex('-0X1p-1075'), -0.0) 1313 self.identical(fromHex('-0x1p-123456789123456789'), -0.0) 1314 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY) 1315 self.identical(fromHex('-0x1.1p-1075'), -TINY) 1316 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY) 1317 1318 # check round-half-even is working correctly near 0 ... 1319 self.identical(fromHex('0x1p-1076'), 0.0) 1320 self.identical(fromHex('0X2p-1076'), 0.0) 1321 self.identical(fromHex('0X3p-1076'), TINY) 1322 self.identical(fromHex('0x4p-1076'), TINY) 1323 self.identical(fromHex('0X5p-1076'), TINY) 1324 self.identical(fromHex('0X6p-1076'), 2*TINY) 1325 self.identical(fromHex('0x7p-1076'), 2*TINY) 1326 self.identical(fromHex('0X8p-1076'), 2*TINY) 1327 self.identical(fromHex('0X9p-1076'), 2*TINY) 1328 self.identical(fromHex('0xap-1076'), 2*TINY) 1329 self.identical(fromHex('0Xbp-1076'), 3*TINY) 1330 self.identical(fromHex('0xcp-1076'), 3*TINY) 1331 self.identical(fromHex('0Xdp-1076'), 3*TINY) 1332 self.identical(fromHex('0Xep-1076'), 4*TINY) 1333 self.identical(fromHex('0xfp-1076'), 4*TINY) 1334 self.identical(fromHex('0x10p-1076'), 4*TINY) 1335 self.identical(fromHex('-0x1p-1076'), -0.0) 1336 self.identical(fromHex('-0X2p-1076'), -0.0) 1337 self.identical(fromHex('-0x3p-1076'), -TINY) 1338 self.identical(fromHex('-0X4p-1076'), -TINY) 1339 self.identical(fromHex('-0x5p-1076'), -TINY) 1340 self.identical(fromHex('-0x6p-1076'), -2*TINY) 1341 self.identical(fromHex('-0X7p-1076'), -2*TINY) 1342 self.identical(fromHex('-0X8p-1076'), -2*TINY) 1343 self.identical(fromHex('-0X9p-1076'), -2*TINY) 1344 self.identical(fromHex('-0Xap-1076'), -2*TINY) 1345 self.identical(fromHex('-0xbp-1076'), -3*TINY) 1346 self.identical(fromHex('-0xcp-1076'), -3*TINY) 1347 self.identical(fromHex('-0Xdp-1076'), -3*TINY) 1348 self.identical(fromHex('-0xep-1076'), -4*TINY) 1349 self.identical(fromHex('-0Xfp-1076'), -4*TINY) 1350 self.identical(fromHex('-0X10p-1076'), -4*TINY) 1351 1352 # ... and near MIN ... 1353 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY) 1354 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY) 1355 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY) 1356 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY) 1357 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY) 1358 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY) 1359 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY) 1360 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY) 1361 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY) 1362 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY) 1363 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY) 1364 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY) 1365 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY) 1366 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY) 1367 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY) 1368 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY) 1369 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY) 1370 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN) 1371 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN) 1372 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN) 1373 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN) 1374 self.identical(fromHex('0x1.00000000000000p-1022'), MIN) 1375 self.identical(fromHex('0x1.00000000000002p-1022'), MIN) 1376 self.identical(fromHex('0x1.00000000000004p-1022'), MIN) 1377 self.identical(fromHex('0x1.00000000000006p-1022'), MIN) 1378 self.identical(fromHex('0x1.00000000000008p-1022'), MIN) 1379 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY) 1380 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY) 1381 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY) 1382 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY) 1383 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY) 1384 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY) 1385 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY) 1386 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY) 1387 1388 # ... and near 1.0. 1389 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS) 1390 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS) 1391 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS) 1392 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS) 1393 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS) 1394 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2) 1395 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2) 1396 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2) 1397 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2) 1398 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2) 1399 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2) 1400 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2) 1401 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0) 1402 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0) 1403 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0) 1404 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0) 1405 self.identical(fromHex('0X1.00000000000000p0'), 1.0) 1406 self.identical(fromHex('0X1.00000000000001p0'), 1.0) 1407 self.identical(fromHex('0x1.00000000000002p0'), 1.0) 1408 self.identical(fromHex('0X1.00000000000003p0'), 1.0) 1409 self.identical(fromHex('0x1.00000000000004p0'), 1.0) 1410 self.identical(fromHex('0X1.00000000000005p0'), 1.0) 1411 self.identical(fromHex('0X1.00000000000006p0'), 1.0) 1412 self.identical(fromHex('0X1.00000000000007p0'), 1.0) 1413 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'), 1414 1.0) 1415 self.identical(fromHex('0x1.00000000000008p0'), 1.0) 1416 self.identical(fromHex('0x1.00000000000008000000000000000001p0'), 1417 1+EPS) 1418 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS) 1419 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS) 1420 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS) 1421 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS) 1422 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS) 1423 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS) 1424 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS) 1425 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS) 1426 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS) 1427 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS) 1428 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS) 1429 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS) 1430 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS) 1431 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS) 1432 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS) 1433 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'), 1434 1.0+EPS) 1435 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS) 1436 self.identical(fromHex('0X1.00000000000018000000000000000001p0'), 1437 1.0+2*EPS) 1438 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS) 1439 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS) 1440 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS) 1441 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS) 1442 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS) 1443 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS) 1444 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS) 1445 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS) 1446 1447 # Regression test for a corner-case bug reported in b.p.o. 44954 1448 self.identical(fromHex('0x.8p-1074'), 0.0) 1449 self.identical(fromHex('0x.80p-1074'), 0.0) 1450 self.identical(fromHex('0x.81p-1074'), TINY) 1451 self.identical(fromHex('0x8p-1078'), 0.0) 1452 self.identical(fromHex('0x8.0p-1078'), 0.0) 1453 self.identical(fromHex('0x8.1p-1078'), TINY) 1454 self.identical(fromHex('0x80p-1082'), 0.0) 1455 self.identical(fromHex('0x81p-1082'), TINY) 1456 self.identical(fromHex('.8p-1074'), 0.0) 1457 self.identical(fromHex('8p-1078'), 0.0) 1458 self.identical(fromHex('-.8p-1074'), -0.0) 1459 self.identical(fromHex('+8p-1078'), 0.0) 1460 1461 def test_roundtrip(self): 1462 def roundtrip(x): 1463 return fromHex(toHex(x)) 1464 1465 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]: 1466 self.identical(x, roundtrip(x)) 1467 self.identical(-x, roundtrip(-x)) 1468 1469 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x. 1470 import random 1471 for i in range(10000): 1472 e = random.randrange(-1200, 1200) 1473 m = random.random() 1474 s = random.choice([1.0, -1.0]) 1475 try: 1476 x = s*ldexp(m, e) 1477 except OverflowError: 1478 pass 1479 else: 1480 self.identical(x, fromHex(toHex(x))) 1481 1482 def test_subclass(self): 1483 class F(float): 1484 def __new__(cls, value): 1485 return float.__new__(cls, value + 1) 1486 1487 f = F.fromhex((1.5).hex()) 1488 self.assertIs(type(f), F) 1489 self.assertEqual(f, 2.5) 1490 1491 class F2(float): 1492 def __init__(self, value): 1493 self.foo = 'bar' 1494 1495 f = F2.fromhex((1.5).hex()) 1496 self.assertIs(type(f), F2) 1497 self.assertEqual(f, 1.5) 1498 self.assertEqual(getattr(f, 'foo', 'none'), 'bar') 1499 1500 1501if __name__ == '__main__': 1502 unittest.main() 1503