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