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