1import unittest 2from test import support 3from test.test_grammar import (VALID_UNDERSCORE_LITERALS, 4 INVALID_UNDERSCORE_LITERALS) 5 6from random import random 7from math import atan2, isnan, copysign 8import operator 9 10INF = float("inf") 11NAN = float("nan") 12# These tests ensure that complex math does the right thing 13 14class ComplexTest(unittest.TestCase): 15 16 def assertAlmostEqual(self, a, b): 17 if isinstance(a, complex): 18 if isinstance(b, complex): 19 unittest.TestCase.assertAlmostEqual(self, a.real, b.real) 20 unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag) 21 else: 22 unittest.TestCase.assertAlmostEqual(self, a.real, b) 23 unittest.TestCase.assertAlmostEqual(self, a.imag, 0.) 24 else: 25 if isinstance(b, complex): 26 unittest.TestCase.assertAlmostEqual(self, a, b.real) 27 unittest.TestCase.assertAlmostEqual(self, 0., b.imag) 28 else: 29 unittest.TestCase.assertAlmostEqual(self, a, b) 30 31 def assertCloseAbs(self, x, y, eps=1e-9): 32 """Return true iff floats x and y "are close".""" 33 # put the one with larger magnitude second 34 if abs(x) > abs(y): 35 x, y = y, x 36 if y == 0: 37 return abs(x) < eps 38 if x == 0: 39 return abs(y) < eps 40 # check that relative difference < eps 41 self.assertTrue(abs((x-y)/y) < eps) 42 43 def assertFloatsAreIdentical(self, x, y): 44 """assert that floats x and y are identical, in the sense that: 45 (1) both x and y are nans, or 46 (2) both x and y are infinities, with the same sign, or 47 (3) both x and y are zeros, with the same sign, or 48 (4) x and y are both finite and nonzero, and x == y 49 50 """ 51 msg = 'floats {!r} and {!r} are not identical' 52 53 if isnan(x) or isnan(y): 54 if isnan(x) and isnan(y): 55 return 56 elif x == y: 57 if x != 0.0: 58 return 59 # both zero; check that signs match 60 elif copysign(1.0, x) == copysign(1.0, y): 61 return 62 else: 63 msg += ': zeros have different signs' 64 self.fail(msg.format(x, y)) 65 66 def assertClose(self, x, y, eps=1e-9): 67 """Return true iff complexes x and y "are close".""" 68 self.assertCloseAbs(x.real, y.real, eps) 69 self.assertCloseAbs(x.imag, y.imag, eps) 70 71 def check_div(self, x, y): 72 """Compute complex z=x*y, and check that z/x==y and z/y==x.""" 73 z = x * y 74 if x != 0: 75 q = z / x 76 self.assertClose(q, y) 77 q = z.__truediv__(x) 78 self.assertClose(q, y) 79 if y != 0: 80 q = z / y 81 self.assertClose(q, x) 82 q = z.__truediv__(y) 83 self.assertClose(q, x) 84 85 def test_truediv(self): 86 simple_real = [float(i) for i in range(-5, 6)] 87 simple_complex = [complex(x, y) for x in simple_real for y in simple_real] 88 for x in simple_complex: 89 for y in simple_complex: 90 self.check_div(x, y) 91 92 # A naive complex division algorithm (such as in 2.0) is very prone to 93 # nonsense errors for these (overflows and underflows). 94 self.check_div(complex(1e200, 1e200), 1+0j) 95 self.check_div(complex(1e-200, 1e-200), 1+0j) 96 97 # Just for fun. 98 for i in range(100): 99 self.check_div(complex(random(), random()), 100 complex(random(), random())) 101 102 self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) 103 self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j) 104 105 self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) 106 self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) 107 108 for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]: 109 z = complex(0, 0) / complex(denom_real, denom_imag) 110 self.assertTrue(isnan(z.real)) 111 self.assertTrue(isnan(z.imag)) 112 113 def test_floordiv(self): 114 self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 1.5+0j) 115 self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j) 116 117 def test_richcompare(self): 118 self.assertIs(complex.__eq__(1+1j, 1<<10000), False) 119 self.assertIs(complex.__lt__(1+1j, None), NotImplemented) 120 self.assertIs(complex.__eq__(1+1j, 1+1j), True) 121 self.assertIs(complex.__eq__(1+1j, 2+2j), False) 122 self.assertIs(complex.__ne__(1+1j, 1+1j), False) 123 self.assertIs(complex.__ne__(1+1j, 2+2j), True) 124 for i in range(1, 100): 125 f = i / 100.0 126 self.assertIs(complex.__eq__(f+0j, f), True) 127 self.assertIs(complex.__ne__(f+0j, f), False) 128 self.assertIs(complex.__eq__(complex(f, f), f), False) 129 self.assertIs(complex.__ne__(complex(f, f), f), True) 130 self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) 131 self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) 132 self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) 133 self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented) 134 self.assertRaises(TypeError, operator.lt, 1+1j, 2+2j) 135 self.assertRaises(TypeError, operator.le, 1+1j, 2+2j) 136 self.assertRaises(TypeError, operator.gt, 1+1j, 2+2j) 137 self.assertRaises(TypeError, operator.ge, 1+1j, 2+2j) 138 self.assertIs(operator.eq(1+1j, 1+1j), True) 139 self.assertIs(operator.eq(1+1j, 2+2j), False) 140 self.assertIs(operator.ne(1+1j, 1+1j), False) 141 self.assertIs(operator.ne(1+1j, 2+2j), True) 142 143 def test_richcompare_boundaries(self): 144 def check(n, deltas, is_equal, imag = 0.0): 145 for delta in deltas: 146 i = n + delta 147 z = complex(i, imag) 148 self.assertIs(complex.__eq__(z, i), is_equal(delta)) 149 self.assertIs(complex.__ne__(z, i), not is_equal(delta)) 150 # For IEEE-754 doubles the following should hold: 151 # x in [2 ** (52 + i), 2 ** (53 + i + 1)] -> x mod 2 ** i == 0 152 # where the interval is representable, of course. 153 for i in range(1, 10): 154 pow = 52 + i 155 mult = 2 ** i 156 check(2 ** pow, range(1, 101), lambda delta: delta % mult == 0) 157 check(2 ** pow, range(1, 101), lambda delta: False, float(i)) 158 check(2 ** 53, range(-100, 0), lambda delta: True) 159 160 def test_mod(self): 161 # % is no longer supported on complex numbers 162 self.assertRaises(TypeError, (1+1j).__mod__, 0+0j) 163 self.assertRaises(TypeError, lambda: (3.33+4.43j) % 0) 164 self.assertRaises(TypeError, (1+1j).__mod__, 4.3j) 165 166 def test_divmod(self): 167 self.assertRaises(TypeError, divmod, 1+1j, 1+0j) 168 self.assertRaises(TypeError, divmod, 1+1j, 0+0j) 169 170 def test_pow(self): 171 self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0) 172 self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0) 173 self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j) 174 self.assertAlmostEqual(pow(1j, -1), 1/1j) 175 self.assertAlmostEqual(pow(1j, 200), 1) 176 self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j) 177 178 a = 3.33+4.43j 179 self.assertEqual(a ** 0j, 1) 180 self.assertEqual(a ** 0.+0.j, 1) 181 182 self.assertEqual(3j ** 0j, 1) 183 self.assertEqual(3j ** 0, 1) 184 185 try: 186 0j ** a 187 except ZeroDivisionError: 188 pass 189 else: 190 self.fail("should fail 0.0 to negative or complex power") 191 192 try: 193 0j ** (3-2j) 194 except ZeroDivisionError: 195 pass 196 else: 197 self.fail("should fail 0.0 to negative or complex power") 198 199 # The following is used to exercise certain code paths 200 self.assertEqual(a ** 105, a ** 105) 201 self.assertEqual(a ** -105, a ** -105) 202 self.assertEqual(a ** -30, a ** -30) 203 204 self.assertEqual(0.0j ** 0, 1) 205 206 b = 5.1+2.3j 207 self.assertRaises(ValueError, pow, a, b, 0) 208 209 def test_boolcontext(self): 210 for i in range(100): 211 self.assertTrue(complex(random() + 1e-6, random() + 1e-6)) 212 self.assertTrue(not complex(0.0, 0.0)) 213 214 def test_conjugate(self): 215 self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) 216 217 def test_constructor(self): 218 class OS: 219 def __init__(self, value): self.value = value 220 def __complex__(self): return self.value 221 class NS(object): 222 def __init__(self, value): self.value = value 223 def __complex__(self): return self.value 224 self.assertEqual(complex(OS(1+10j)), 1+10j) 225 self.assertEqual(complex(NS(1+10j)), 1+10j) 226 self.assertRaises(TypeError, complex, OS(None)) 227 self.assertRaises(TypeError, complex, NS(None)) 228 self.assertRaises(TypeError, complex, {}) 229 self.assertRaises(TypeError, complex, NS(1.5)) 230 self.assertRaises(TypeError, complex, NS(1)) 231 232 self.assertAlmostEqual(complex("1+10j"), 1+10j) 233 self.assertAlmostEqual(complex(10), 10+0j) 234 self.assertAlmostEqual(complex(10.0), 10+0j) 235 self.assertAlmostEqual(complex(10), 10+0j) 236 self.assertAlmostEqual(complex(10+0j), 10+0j) 237 self.assertAlmostEqual(complex(1,10), 1+10j) 238 self.assertAlmostEqual(complex(1,10), 1+10j) 239 self.assertAlmostEqual(complex(1,10.0), 1+10j) 240 self.assertAlmostEqual(complex(1,10), 1+10j) 241 self.assertAlmostEqual(complex(1,10), 1+10j) 242 self.assertAlmostEqual(complex(1,10.0), 1+10j) 243 self.assertAlmostEqual(complex(1.0,10), 1+10j) 244 self.assertAlmostEqual(complex(1.0,10), 1+10j) 245 self.assertAlmostEqual(complex(1.0,10.0), 1+10j) 246 self.assertAlmostEqual(complex(3.14+0j), 3.14+0j) 247 self.assertAlmostEqual(complex(3.14), 3.14+0j) 248 self.assertAlmostEqual(complex(314), 314.0+0j) 249 self.assertAlmostEqual(complex(314), 314.0+0j) 250 self.assertAlmostEqual(complex(3.14+0j, 0j), 3.14+0j) 251 self.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j) 252 self.assertAlmostEqual(complex(314, 0), 314.0+0j) 253 self.assertAlmostEqual(complex(314, 0), 314.0+0j) 254 self.assertAlmostEqual(complex(0j, 3.14j), -3.14+0j) 255 self.assertAlmostEqual(complex(0.0, 3.14j), -3.14+0j) 256 self.assertAlmostEqual(complex(0j, 3.14), 3.14j) 257 self.assertAlmostEqual(complex(0.0, 3.14), 3.14j) 258 self.assertAlmostEqual(complex("1"), 1+0j) 259 self.assertAlmostEqual(complex("1j"), 1j) 260 self.assertAlmostEqual(complex(), 0) 261 self.assertAlmostEqual(complex("-1"), -1) 262 self.assertAlmostEqual(complex("+1"), +1) 263 self.assertAlmostEqual(complex("(1+2j)"), 1+2j) 264 self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) 265 self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j) 266 self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j) 267 self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j) 268 self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j) 269 self.assertAlmostEqual(complex("J"), 1j) 270 self.assertAlmostEqual(complex("( j )"), 1j) 271 self.assertAlmostEqual(complex("+J"), 1j) 272 self.assertAlmostEqual(complex("( -j)"), -1j) 273 self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j) 274 self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j) 275 self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j) 276 277 class complex2(complex): pass 278 self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) 279 self.assertAlmostEqual(complex(real=17, imag=23), 17+23j) 280 self.assertAlmostEqual(complex(real=17+23j), 17+23j) 281 self.assertAlmostEqual(complex(real=17+23j, imag=23), 17+46j) 282 self.assertAlmostEqual(complex(real=1+2j, imag=3+4j), -3+5j) 283 284 # check that the sign of a zero in the real or imaginary part 285 # is preserved when constructing from two floats. (These checks 286 # are harmless on systems without support for signed zeros.) 287 def split_zeros(x): 288 """Function that produces different results for 0. and -0.""" 289 return atan2(x, -1.) 290 291 self.assertEqual(split_zeros(complex(1., 0.).imag), split_zeros(0.)) 292 self.assertEqual(split_zeros(complex(1., -0.).imag), split_zeros(-0.)) 293 self.assertEqual(split_zeros(complex(0., 1.).real), split_zeros(0.)) 294 self.assertEqual(split_zeros(complex(-0., 1.).real), split_zeros(-0.)) 295 296 c = 3.14 + 1j 297 self.assertTrue(complex(c) is c) 298 del c 299 300 self.assertRaises(TypeError, complex, "1", "1") 301 self.assertRaises(TypeError, complex, 1, "1") 302 303 # SF bug 543840: complex(string) accepts strings with \0 304 # Fixed in 2.3. 305 self.assertRaises(ValueError, complex, '1+1j\0j') 306 307 self.assertRaises(TypeError, int, 5+3j) 308 self.assertRaises(TypeError, int, 5+3j) 309 self.assertRaises(TypeError, float, 5+3j) 310 self.assertRaises(ValueError, complex, "") 311 self.assertRaises(TypeError, complex, None) 312 self.assertRaisesRegex(TypeError, "not 'NoneType'", complex, None) 313 self.assertRaises(ValueError, complex, "\0") 314 self.assertRaises(ValueError, complex, "3\09") 315 self.assertRaises(TypeError, complex, "1", "2") 316 self.assertRaises(TypeError, complex, "1", 42) 317 self.assertRaises(TypeError, complex, 1, "2") 318 self.assertRaises(ValueError, complex, "1+") 319 self.assertRaises(ValueError, complex, "1+1j+1j") 320 self.assertRaises(ValueError, complex, "--") 321 self.assertRaises(ValueError, complex, "(1+2j") 322 self.assertRaises(ValueError, complex, "1+2j)") 323 self.assertRaises(ValueError, complex, "1+(2j)") 324 self.assertRaises(ValueError, complex, "(1+2j)123") 325 self.assertRaises(ValueError, complex, "x") 326 self.assertRaises(ValueError, complex, "1j+2") 327 self.assertRaises(ValueError, complex, "1e1ej") 328 self.assertRaises(ValueError, complex, "1e++1ej") 329 self.assertRaises(ValueError, complex, ")1+2j(") 330 self.assertRaisesRegex( 331 TypeError, 332 "first argument must be a string or a number, not 'dict'", 333 complex, {1:2}, 1) 334 self.assertRaisesRegex( 335 TypeError, 336 "second argument must be a number, not 'dict'", 337 complex, 1, {1:2}) 338 # the following three are accepted by Python 2.6 339 self.assertRaises(ValueError, complex, "1..1j") 340 self.assertRaises(ValueError, complex, "1.11.1j") 341 self.assertRaises(ValueError, complex, "1e1.1j") 342 343 # check that complex accepts long unicode strings 344 self.assertEqual(type(complex("1"*500)), complex) 345 # check whitespace processing 346 self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j) 347 # Invalid unicode string 348 # See bpo-34087 349 self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f') 350 351 class EvilExc(Exception): 352 pass 353 354 class evilcomplex: 355 def __complex__(self): 356 raise EvilExc 357 358 self.assertRaises(EvilExc, complex, evilcomplex()) 359 360 class float2: 361 def __init__(self, value): 362 self.value = value 363 def __float__(self): 364 return self.value 365 366 self.assertAlmostEqual(complex(float2(42.)), 42) 367 self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) 368 self.assertRaises(TypeError, complex, float2(None)) 369 370 class MyIndex: 371 def __init__(self, value): 372 self.value = value 373 def __index__(self): 374 return self.value 375 376 self.assertAlmostEqual(complex(MyIndex(42)), 42.0+0.0j) 377 self.assertAlmostEqual(complex(123, MyIndex(42)), 123.0+42.0j) 378 self.assertRaises(OverflowError, complex, MyIndex(2**2000)) 379 self.assertRaises(OverflowError, complex, 123, MyIndex(2**2000)) 380 381 class MyInt: 382 def __int__(self): 383 return 42 384 385 self.assertRaises(TypeError, complex, MyInt()) 386 self.assertRaises(TypeError, complex, 123, MyInt()) 387 388 class complex0(complex): 389 """Test usage of __complex__() when inheriting from 'complex'""" 390 def __complex__(self): 391 return 42j 392 393 class complex1(complex): 394 """Test usage of __complex__() with a __new__() method""" 395 def __new__(self, value=0j): 396 return complex.__new__(self, 2*value) 397 def __complex__(self): 398 return self 399 400 class complex2(complex): 401 """Make sure that __complex__() calls fail if anything other than a 402 complex is returned""" 403 def __complex__(self): 404 return None 405 406 self.assertEqual(complex(complex0(1j)), 42j) 407 with self.assertWarns(DeprecationWarning): 408 self.assertEqual(complex(complex1(1j)), 2j) 409 self.assertRaises(TypeError, complex, complex2(1j)) 410 411 @support.requires_IEEE_754 412 def test_constructor_special_numbers(self): 413 class complex2(complex): 414 pass 415 for x in 0.0, -0.0, INF, -INF, NAN: 416 for y in 0.0, -0.0, INF, -INF, NAN: 417 with self.subTest(x=x, y=y): 418 z = complex(x, y) 419 self.assertFloatsAreIdentical(z.real, x) 420 self.assertFloatsAreIdentical(z.imag, y) 421 z = complex2(x, y) 422 self.assertIs(type(z), complex2) 423 self.assertFloatsAreIdentical(z.real, x) 424 self.assertFloatsAreIdentical(z.imag, y) 425 z = complex(complex2(x, y)) 426 self.assertIs(type(z), complex) 427 self.assertFloatsAreIdentical(z.real, x) 428 self.assertFloatsAreIdentical(z.imag, y) 429 z = complex2(complex(x, y)) 430 self.assertIs(type(z), complex2) 431 self.assertFloatsAreIdentical(z.real, x) 432 self.assertFloatsAreIdentical(z.imag, y) 433 434 def test_underscores(self): 435 # check underscores 436 for lit in VALID_UNDERSCORE_LITERALS: 437 if not any(ch in lit for ch in 'xXoObB'): 438 self.assertEqual(complex(lit), eval(lit)) 439 self.assertEqual(complex(lit), complex(lit.replace('_', ''))) 440 for lit in INVALID_UNDERSCORE_LITERALS: 441 if lit in ('0_7', '09_99'): # octals are not recognized here 442 continue 443 if not any(ch in lit for ch in 'xXoObB'): 444 self.assertRaises(ValueError, complex, lit) 445 446 def test_hash(self): 447 for x in range(-30, 30): 448 self.assertEqual(hash(x), hash(complex(x, 0))) 449 x /= 3.0 # now check against floating point 450 self.assertEqual(hash(x), hash(complex(x, 0.))) 451 452 def test_abs(self): 453 nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)] 454 for num in nums: 455 self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num)) 456 457 def test_repr_str(self): 458 def test(v, expected, test_fn=self.assertEqual): 459 test_fn(repr(v), expected) 460 test_fn(str(v), expected) 461 462 test(1+6j, '(1+6j)') 463 test(1-6j, '(1-6j)') 464 465 test(-(1+0j), '(-1+-0j)', test_fn=self.assertNotEqual) 466 467 test(complex(1., INF), "(1+infj)") 468 test(complex(1., -INF), "(1-infj)") 469 test(complex(INF, 1), "(inf+1j)") 470 test(complex(-INF, INF), "(-inf+infj)") 471 test(complex(NAN, 1), "(nan+1j)") 472 test(complex(1, NAN), "(1+nanj)") 473 test(complex(NAN, NAN), "(nan+nanj)") 474 475 test(complex(0, INF), "infj") 476 test(complex(0, -INF), "-infj") 477 test(complex(0, NAN), "nanj") 478 479 self.assertEqual(1-6j,complex(repr(1-6j))) 480 self.assertEqual(1+6j,complex(repr(1+6j))) 481 self.assertEqual(-6j,complex(repr(-6j))) 482 self.assertEqual(6j,complex(repr(6j))) 483 484 @support.requires_IEEE_754 485 def test_negative_zero_repr_str(self): 486 def test(v, expected, test_fn=self.assertEqual): 487 test_fn(repr(v), expected) 488 test_fn(str(v), expected) 489 490 test(complex(0., 1.), "1j") 491 test(complex(-0., 1.), "(-0+1j)") 492 test(complex(0., -1.), "-1j") 493 test(complex(-0., -1.), "(-0-1j)") 494 495 test(complex(0., 0.), "0j") 496 test(complex(0., -0.), "-0j") 497 test(complex(-0., 0.), "(-0+0j)") 498 test(complex(-0., -0.), "(-0-0j)") 499 500 def test_neg(self): 501 self.assertEqual(-(1+6j), -1-6j) 502 503 def test_file(self): 504 a = 3.33+4.43j 505 b = 5.1+2.3j 506 507 fo = None 508 try: 509 fo = open(support.TESTFN, "w") 510 print(a, b, file=fo) 511 fo.close() 512 fo = open(support.TESTFN, "r") 513 self.assertEqual(fo.read(), ("%s %s\n" % (a, b))) 514 finally: 515 if (fo is not None) and (not fo.closed): 516 fo.close() 517 support.unlink(support.TESTFN) 518 519 def test_getnewargs(self): 520 self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0)) 521 self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0)) 522 self.assertEqual((2j).__getnewargs__(), (0.0, 2.0)) 523 self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0)) 524 self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF)) 525 self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0)) 526 527 @support.requires_IEEE_754 528 def test_plus_minus_0j(self): 529 # test that -0j and 0j literals are not identified 530 z1, z2 = 0j, -0j 531 self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.)) 532 self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.)) 533 534 @support.requires_IEEE_754 535 def test_negated_imaginary_literal(self): 536 z0 = -0j 537 z1 = -7j 538 z2 = -1e1000j 539 # Note: In versions of Python < 3.2, a negated imaginary literal 540 # accidentally ended up with real part 0.0 instead of -0.0, thanks to a 541 # modification during CST -> AST translation (see issue #9011). That's 542 # fixed in Python 3.2. 543 self.assertFloatsAreIdentical(z0.real, -0.0) 544 self.assertFloatsAreIdentical(z0.imag, -0.0) 545 self.assertFloatsAreIdentical(z1.real, -0.0) 546 self.assertFloatsAreIdentical(z1.imag, -7.0) 547 self.assertFloatsAreIdentical(z2.real, -0.0) 548 self.assertFloatsAreIdentical(z2.imag, -INF) 549 550 @support.requires_IEEE_754 551 def test_overflow(self): 552 self.assertEqual(complex("1e500"), complex(INF, 0.0)) 553 self.assertEqual(complex("-1e500j"), complex(0.0, -INF)) 554 self.assertEqual(complex("-1e500+1.8e308j"), complex(-INF, INF)) 555 556 @support.requires_IEEE_754 557 def test_repr_roundtrip(self): 558 vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] 559 vals += [-v for v in vals] 560 561 # complex(repr(z)) should recover z exactly, even for complex 562 # numbers involving an infinity, nan, or negative zero 563 for x in vals: 564 for y in vals: 565 z = complex(x, y) 566 roundtrip = complex(repr(z)) 567 self.assertFloatsAreIdentical(z.real, roundtrip.real) 568 self.assertFloatsAreIdentical(z.imag, roundtrip.imag) 569 570 # if we predefine some constants, then eval(repr(z)) should 571 # also work, except that it might change the sign of zeros 572 inf, nan = float('inf'), float('nan') 573 infj, nanj = complex(0.0, inf), complex(0.0, nan) 574 for x in vals: 575 for y in vals: 576 z = complex(x, y) 577 roundtrip = eval(repr(z)) 578 # adding 0.0 has no effect beside changing -0.0 to 0.0 579 self.assertFloatsAreIdentical(0.0 + z.real, 580 0.0 + roundtrip.real) 581 self.assertFloatsAreIdentical(0.0 + z.imag, 582 0.0 + roundtrip.imag) 583 584 def test_format(self): 585 # empty format string is same as str() 586 self.assertEqual(format(1+3j, ''), str(1+3j)) 587 self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j)) 588 self.assertEqual(format(3j, ''), str(3j)) 589 self.assertEqual(format(3.2j, ''), str(3.2j)) 590 self.assertEqual(format(3+0j, ''), str(3+0j)) 591 self.assertEqual(format(3.2+0j, ''), str(3.2+0j)) 592 593 # empty presentation type should still be analogous to str, 594 # even when format string is nonempty (issue #5920). 595 self.assertEqual(format(3.2+0j, '-'), str(3.2+0j)) 596 self.assertEqual(format(3.2+0j, '<'), str(3.2+0j)) 597 z = 4/7. - 100j/7. 598 self.assertEqual(format(z, ''), str(z)) 599 self.assertEqual(format(z, '-'), str(z)) 600 self.assertEqual(format(z, '<'), str(z)) 601 self.assertEqual(format(z, '10'), str(z)) 602 z = complex(0.0, 3.0) 603 self.assertEqual(format(z, ''), str(z)) 604 self.assertEqual(format(z, '-'), str(z)) 605 self.assertEqual(format(z, '<'), str(z)) 606 self.assertEqual(format(z, '2'), str(z)) 607 z = complex(-0.0, 2.0) 608 self.assertEqual(format(z, ''), str(z)) 609 self.assertEqual(format(z, '-'), str(z)) 610 self.assertEqual(format(z, '<'), str(z)) 611 self.assertEqual(format(z, '3'), str(z)) 612 613 self.assertEqual(format(1+3j, 'g'), '1+3j') 614 self.assertEqual(format(3j, 'g'), '0+3j') 615 self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j') 616 617 self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j') 618 self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j') 619 self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j') 620 self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j') 621 self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j') 622 self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j') 623 self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j') 624 625 self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j') 626 self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j') 627 self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j') 628 self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j') 629 self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j') 630 self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j') 631 self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j') 632 633 self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ') 634 self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************') 635 self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j') 636 self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ') 637 self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ') 638 self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)') 639 self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') 640 self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') 641 642 self.assertEqual(format(1.5+3j, '20.2f'), ' 1.50+3.00j') 643 self.assertEqual(format(1.5+3j, '>20.2f'), ' 1.50+3.00j') 644 self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') 645 self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') 646 self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') 647 self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ') 648 self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ') 649 self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j') 650 651 # Issue 7094: Alternate formatting (specified by #) 652 self.assertEqual(format(1+1j, '.0e'), '1e+00+1e+00j') 653 self.assertEqual(format(1+1j, '#.0e'), '1.e+00+1.e+00j') 654 self.assertEqual(format(1+1j, '.0f'), '1+1j') 655 self.assertEqual(format(1+1j, '#.0f'), '1.+1.j') 656 self.assertEqual(format(1.1+1.1j, 'g'), '1.1+1.1j') 657 self.assertEqual(format(1.1+1.1j, '#g'), '1.10000+1.10000j') 658 659 # Alternate doesn't make a difference for these, they format the same with or without it 660 self.assertEqual(format(1+1j, '.1e'), '1.0e+00+1.0e+00j') 661 self.assertEqual(format(1+1j, '#.1e'), '1.0e+00+1.0e+00j') 662 self.assertEqual(format(1+1j, '.1f'), '1.0+1.0j') 663 self.assertEqual(format(1+1j, '#.1f'), '1.0+1.0j') 664 665 # Misc. other alternate tests 666 self.assertEqual(format((-1.5+0.5j), '#f'), '-1.500000+0.500000j') 667 self.assertEqual(format((-1.5+0.5j), '#.0f'), '-2.+0.j') 668 self.assertEqual(format((-1.5+0.5j), '#e'), '-1.500000e+00+5.000000e-01j') 669 self.assertEqual(format((-1.5+0.5j), '#.0e'), '-2.e+00+5.e-01j') 670 self.assertEqual(format((-1.5+0.5j), '#g'), '-1.50000+0.500000j') 671 self.assertEqual(format((-1.5+0.5j), '.0g'), '-2+0.5j') 672 self.assertEqual(format((-1.5+0.5j), '#.0g'), '-2.+0.5j') 673 674 # zero padding is invalid 675 self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f') 676 677 # '=' alignment is invalid 678 self.assertRaises(ValueError, (1.5+3j).__format__, '=20') 679 680 # integer presentation types are an error 681 for t in 'bcdoxX': 682 self.assertRaises(ValueError, (1.5+0.5j).__format__, t) 683 684 # make sure everything works in ''.format() 685 self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') 686 687 # issue 3382 688 self.assertEqual(format(complex(NAN, NAN), 'f'), 'nan+nanj') 689 self.assertEqual(format(complex(1, NAN), 'f'), '1.000000+nanj') 690 self.assertEqual(format(complex(NAN, 1), 'f'), 'nan+1.000000j') 691 self.assertEqual(format(complex(NAN, -1), 'f'), 'nan-1.000000j') 692 self.assertEqual(format(complex(NAN, NAN), 'F'), 'NAN+NANj') 693 self.assertEqual(format(complex(1, NAN), 'F'), '1.000000+NANj') 694 self.assertEqual(format(complex(NAN, 1), 'F'), 'NAN+1.000000j') 695 self.assertEqual(format(complex(NAN, -1), 'F'), 'NAN-1.000000j') 696 self.assertEqual(format(complex(INF, INF), 'f'), 'inf+infj') 697 self.assertEqual(format(complex(1, INF), 'f'), '1.000000+infj') 698 self.assertEqual(format(complex(INF, 1), 'f'), 'inf+1.000000j') 699 self.assertEqual(format(complex(INF, -1), 'f'), 'inf-1.000000j') 700 self.assertEqual(format(complex(INF, INF), 'F'), 'INF+INFj') 701 self.assertEqual(format(complex(1, INF), 'F'), '1.000000+INFj') 702 self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j') 703 self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j') 704 705def test_main(): 706 support.run_unittest(ComplexTest) 707 708if __name__ == "__main__": 709 test_main() 710