2 from test
import test_support
5 warnings
.filterwarnings(
7 category
=DeprecationWarning,
8 message
=".*complex divmod.*are deprecated"
11 from random
import random
12 from math
import atan2
, isnan
, copysign
16 # These tests ensure that complex math does the right thing
18 class ComplexTest(unittest
.TestCase
):
20 def assertAlmostEqual(self
, a
, b
):
21 if isinstance(a
, complex):
22 if isinstance(b
, complex):
23 unittest
.TestCase
.assertAlmostEqual(self
, a
.real
, b
.real
)
24 unittest
.TestCase
.assertAlmostEqual(self
, a
.imag
, b
.imag
)
26 unittest
.TestCase
.assertAlmostEqual(self
, a
.real
, b
)
27 unittest
.TestCase
.assertAlmostEqual(self
, a
.imag
, 0.)
29 if isinstance(b
, complex):
30 unittest
.TestCase
.assertAlmostEqual(self
, a
, b
.real
)
31 unittest
.TestCase
.assertAlmostEqual(self
, 0., b
.imag
)
33 unittest
.TestCase
.assertAlmostEqual(self
, a
, b
)
35 def assertCloseAbs(self
, x
, y
, eps
=1e-9):
36 """Return true iff floats x and y "are close\""""
37 # put the one with larger magnitude second
44 # check that relative difference < eps
45 self.assert_(abs((x-y)/y) < eps)
47 def assertFloatsAreIdentical(self, x, y):
48 """assert that floats x
and y are identical
, in the sense that
:
49 (1) both x
and y are nans
, or
50 (2) both x
and y are infinities
, with the same sign
, or
51 (3) both x
and y are zeros
, with the same sign
, or
52 (4) x
and y are both finite
and nonzero
, and x
== y
55 msg = 'floats {!r} and {!r} are not identical'
57 if isnan(x) or isnan(y):
58 if isnan(x) and isnan(y):
63 # both zero; check that signs match
64 elif copysign(1.0, x) == copysign(1.0, y):
67 msg += ': zeros have different signs'
68 self.fail(msg.format(x, y))
70 def assertClose(self, x, y, eps=1e-9):
71 """Return true iff complexes x
and y
"are close\""""
72 self
.assertCloseAbs(x
.real
, y
.real
, eps
)
73 self
.assertCloseAbs(x
.imag
, y
.imag
, eps
)
75 def assertIs(self
, a
, b
):
78 def check_div(self
, x
, y
):
79 """Compute complex z=x*y, and check that z/x==y and z/y==x."""
83 self
.assertClose(q
, y
)
85 self
.assertClose(q
, y
)
87 self
.assertClose(q
, y
)
90 self
.assertClose(q
, x
)
92 self
.assertClose(q
, x
)
94 self
.assertClose(q
, x
)
97 simple_real
= [float(i
) for i
in xrange(-5, 6)]
98 simple_complex
= [complex(x
, y
) for x
in simple_real
for y
in simple_real
]
99 for x
in simple_complex
:
100 for y
in simple_complex
:
103 # A naive complex division algorithm (such as in 2.0) is very prone to
104 # nonsense errors for these (overflows and underflows).
105 self
.check_div(complex(1e200
, 1e200
), 1+0j
)
106 self
.check_div(complex(1e-200, 1e-200), 1+0j
)
109 for i
in xrange(100):
110 self
.check_div(complex(random(), random()),
111 complex(random(), random()))
113 self
.assertRaises(ZeroDivisionError, complex.__div
__, 1+1j
, 0+0j
)
114 # FIXME: The following currently crashes on Alpha
115 # self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j)
117 def test_truediv(self
):
118 self
.assertAlmostEqual(complex.__truediv
__(2+0j
, 1+1j
), 1-1j
)
119 self
.assertRaises(ZeroDivisionError, complex.__truediv
__, 1+1j
, 0+0j
)
121 def test_floordiv(self
):
122 self
.assertAlmostEqual(complex.__floordiv
__(3+0j
, 1.5+0j
), 2)
123 self
.assertRaises(ZeroDivisionError, complex.__floordiv
__, 3+0j
, 0+0j
)
125 def test_coerce(self
):
126 self
.assertRaises(OverflowError, complex.__coerce
__, 1+1j
, 1L<<10000)
128 def test_richcompare(self
):
129 self
.assertRaises(OverflowError, complex.__eq
__, 1+1j
, 1L<<10000)
130 self
.assertEqual(complex.__lt
__(1+1j
, None), NotImplemented)
131 self
.assertIs(complex.__eq
__(1+1j
, 1+1j
), True)
132 self
.assertIs(complex.__eq
__(1+1j
, 2+2j
), False)
133 self
.assertIs(complex.__ne
__(1+1j
, 1+1j
), False)
134 self
.assertIs(complex.__ne
__(1+1j
, 2+2j
), True)
135 self
.assertRaises(TypeError, complex.__lt
__, 1+1j
, 2+2j
)
136 self
.assertRaises(TypeError, complex.__le
__, 1+1j
, 2+2j
)
137 self
.assertRaises(TypeError, complex.__gt
__, 1+1j
, 2+2j
)
138 self
.assertRaises(TypeError, complex.__ge
__, 1+1j
, 2+2j
)
141 self
.assertRaises(ZeroDivisionError, (1+1j
).__mod
__, 0+0j
)
146 except ZeroDivisionError:
149 self
.fail("modulo parama can't be 0")
151 def test_divmod(self
):
152 self
.assertRaises(ZeroDivisionError, divmod, 1+1j
, 0+0j
)
155 self
.assertAlmostEqual(pow(1+1j
, 0+0j
), 1.0)
156 self
.assertAlmostEqual(pow(0+0j
, 2+0j
), 0.0)
157 self
.assertRaises(ZeroDivisionError, pow, 0+0j
, 1j
)
158 self
.assertAlmostEqual(pow(1j
, -1), 1/1j
)
159 self
.assertAlmostEqual(pow(1j
, 200), 1)
160 self
.assertRaises(ValueError, pow, 1+1j
, 1+1j
, 1+1j
)
163 self
.assertEqual(a
** 0j
, 1)
164 self
.assertEqual(a
** 0.+0.j
, 1)
166 self
.assertEqual(3j
** 0j
, 1)
167 self
.assertEqual(3j
** 0, 1)
171 except ZeroDivisionError:
174 self
.fail("should fail 0.0 to negative or complex power")
178 except ZeroDivisionError:
181 self
.fail("should fail 0.0 to negative or complex power")
183 # The following is used to exercise certain code paths
184 self
.assertEqual(a
** 105, a
** 105)
185 self
.assertEqual(a
** -105, a
** -105)
186 self
.assertEqual(a
** -30, a
** -30)
188 self
.assertEqual(0.0j
** 0, 1)
191 self
.assertRaises(ValueError, pow, a
, b
, 0)
193 def test_boolcontext(self
):
194 for i
in xrange(100):
195 self
.assert_(complex(random() + 1e-6, random() + 1e-6))
196 self
.assert_(not complex(0.0, 0.0))
198 def test_conjugate(self
):
199 self
.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j
)
201 def test_constructor(self
):
203 def __init__(self
, value
): self
.value
= value
204 def __complex__(self
): return self
.value
206 def __init__(self
, value
): self
.value
= value
207 def __complex__(self
): return self
.value
208 self
.assertEqual(complex(OS(1+10j
)), 1+10j
)
209 self
.assertEqual(complex(NS(1+10j
)), 1+10j
)
210 self
.assertRaises(TypeError, complex, OS(None))
211 self
.assertRaises(TypeError, complex, NS(None))
213 self
.assertAlmostEqual(complex("1+10j"), 1+10j
)
214 self
.assertAlmostEqual(complex(10), 10+0j
)
215 self
.assertAlmostEqual(complex(10.0), 10+0j
)
216 self
.assertAlmostEqual(complex(10L), 10+0j
)
217 self
.assertAlmostEqual(complex(10+0j
), 10+0j
)
218 self
.assertAlmostEqual(complex(1,10), 1+10j
)
219 self
.assertAlmostEqual(complex(1,10L), 1+10j
)
220 self
.assertAlmostEqual(complex(1,10.0), 1+10j
)
221 self
.assertAlmostEqual(complex(1L,10), 1+10j
)
222 self
.assertAlmostEqual(complex(1L,10L), 1+10j
)
223 self
.assertAlmostEqual(complex(1L,10.0), 1+10j
)
224 self
.assertAlmostEqual(complex(1.0,10), 1+10j
)
225 self
.assertAlmostEqual(complex(1.0,10L), 1+10j
)
226 self
.assertAlmostEqual(complex(1.0,10.0), 1+10j
)
227 self
.assertAlmostEqual(complex(3.14+0j
), 3.14+0j
)
228 self
.assertAlmostEqual(complex(3.14), 3.14+0j
)
229 self
.assertAlmostEqual(complex(314), 314.0+0j
)
230 self
.assertAlmostEqual(complex(314L), 314.0+0j
)
231 self
.assertAlmostEqual(complex(3.14+0j
, 0j
), 3.14+0j
)
232 self
.assertAlmostEqual(complex(3.14, 0.0), 3.14+0j
)
233 self
.assertAlmostEqual(complex(314, 0), 314.0+0j
)
234 self
.assertAlmostEqual(complex(314L, 0L), 314.0+0j
)
235 self
.assertAlmostEqual(complex(0j
, 3.14j
), -3.14+0j
)
236 self
.assertAlmostEqual(complex(0.0, 3.14j
), -3.14+0j
)
237 self
.assertAlmostEqual(complex(0j
, 3.14), 3.14j
)
238 self
.assertAlmostEqual(complex(0.0, 3.14), 3.14j
)
239 self
.assertAlmostEqual(complex("1"), 1+0j
)
240 self
.assertAlmostEqual(complex("1j"), 1j
)
241 self
.assertAlmostEqual(complex(), 0)
242 self
.assertAlmostEqual(complex("-1"), -1)
243 self
.assertAlmostEqual(complex("+1"), +1)
244 self
.assertAlmostEqual(complex("(1+2j)"), 1+2j
)
245 self
.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j
)
246 self
.assertAlmostEqual(complex("3.14+1J"), 3.14+1j
)
247 self
.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j
)
248 self
.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j
)
249 self
.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j
)
250 self
.assertAlmostEqual(complex("J"), 1j
)
251 self
.assertAlmostEqual(complex("( j )"), 1j
)
252 self
.assertAlmostEqual(complex("+J"), 1j
)
253 self
.assertAlmostEqual(complex("( -j)"), -1j
)
254 self
.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j
)
255 self
.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j
)
256 self
.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j
)
258 class complex2(complex): pass
259 self
.assertAlmostEqual(complex(complex2(1+1j
)), 1+1j
)
260 self
.assertAlmostEqual(complex(real
=17, imag
=23), 17+23j
)
261 self
.assertAlmostEqual(complex(real
=17+23j
), 17+23j
)
262 self
.assertAlmostEqual(complex(real
=17+23j
, imag
=23), 17+46j
)
263 self
.assertAlmostEqual(complex(real
=1+2j
, imag
=3+4j
), -3+5j
)
265 # check that the sign of a zero in the real or imaginary part
266 # is preserved when constructing from two floats. (These checks
267 # are harmless on systems without support for signed zeros.)
269 """Function that produces different results for 0. and -0."""
272 self
.assertEqual(split_zeros(complex(1., 0.).imag
), split_zeros(0.))
273 self
.assertEqual(split_zeros(complex(1., -0.).imag
), split_zeros(-0.))
274 self
.assertEqual(split_zeros(complex(0., 1.).real
), split_zeros(0.))
275 self
.assertEqual(split_zeros(complex(-0., 1.).real
), split_zeros(-0.))
278 self
.assert_(complex(c
) is c
)
281 self
.assertRaises(TypeError, complex, "1", "1")
282 self
.assertRaises(TypeError, complex, 1, "1")
284 if test_support
.have_unicode
:
285 self
.assertEqual(complex(unicode(" 3.14+J ")), 3.14+1j
)
287 # SF bug 543840: complex(string) accepts strings with \0
289 self
.assertRaises(ValueError, complex, '1+1j\0j')
291 self
.assertRaises(TypeError, int, 5+3j
)
292 self
.assertRaises(TypeError, long, 5+3j
)
293 self
.assertRaises(TypeError, float, 5+3j
)
294 self
.assertRaises(ValueError, complex, "")
295 self
.assertRaises(TypeError, complex, None)
296 self
.assertRaises(ValueError, complex, "\0")
297 self
.assertRaises(ValueError, complex, "3\09")
298 self
.assertRaises(TypeError, complex, "1", "2")
299 self
.assertRaises(TypeError, complex, "1", 42)
300 self
.assertRaises(TypeError, complex, 1, "2")
301 self
.assertRaises(ValueError, complex, "1+")
302 self
.assertRaises(ValueError, complex, "1+1j+1j")
303 self
.assertRaises(ValueError, complex, "--")
304 self
.assertRaises(ValueError, complex, "(1+2j")
305 self
.assertRaises(ValueError, complex, "1+2j)")
306 self
.assertRaises(ValueError, complex, "1+(2j)")
307 self
.assertRaises(ValueError, complex, "(1+2j)123")
308 if test_support
.have_unicode
:
309 self
.assertRaises(ValueError, complex, unicode("1"*500))
310 self
.assertRaises(ValueError, complex, unicode("x"))
311 self
.assertRaises(ValueError, complex, "1j+2")
312 self
.assertRaises(ValueError, complex, "1e1ej")
313 self
.assertRaises(ValueError, complex, "1e++1ej")
314 self
.assertRaises(ValueError, complex, ")1+2j(")
315 # the following three are accepted by Python 2.6
316 self
.assertRaises(ValueError, complex, "1..1j")
317 self
.assertRaises(ValueError, complex, "1.11.1j")
318 self
.assertRaises(ValueError, complex, "1e1.1j")
320 class EvilExc(Exception):
324 def __complex__(self
):
327 self
.assertRaises(EvilExc
, complex, evilcomplex())
330 def __init__(self
, value
):
335 self
.assertAlmostEqual(complex(float2(42.)), 42)
336 self
.assertAlmostEqual(complex(real
=float2(17.), imag
=float2(23.)), 17+23j
)
337 self
.assertRaises(TypeError, complex, float2(None))
339 class complex0(complex):
340 """Test usage of __complex__() when inheriting from 'complex'"""
341 def __complex__(self
):
344 class complex1(complex):
345 """Test usage of __complex__() with a __new__() method"""
346 def __new__(self
, value
=0j
):
347 return complex.__new
__(self
, 2*value
)
348 def __complex__(self
):
351 class complex2(complex):
352 """Make sure that __complex__() calls fail if anything other than a
353 complex is returned"""
354 def __complex__(self
):
357 self
.assertAlmostEqual(complex(complex0(1j
)), 42j
)
358 self
.assertAlmostEqual(complex(complex1(1j
)), 2j
)
359 self
.assertRaises(TypeError, complex, complex2(1j
))
362 for x
in xrange(-30, 30):
363 self
.assertEqual(hash(x
), hash(complex(x
, 0)))
364 x
/= 3.0 # now check against floating point
365 self
.assertEqual(hash(x
), hash(complex(x
, 0.)))
368 nums
= [complex(x
/3., y
/7.) for x
in xrange(-9,9) for y
in xrange(-9,9)]
370 self
.assertAlmostEqual((num
.real
**2 + num
.imag
**2) ** 0.5, abs(num
))
373 self
.assertEqual(repr(1+6j
), '(1+6j)')
374 self
.assertEqual(repr(1-6j
), '(1-6j)')
376 self
.assertNotEqual(repr(-(1+0j
)), '(-1+-0j)')
378 self
.assertEqual(1-6j
,complex(repr(1-6j
)))
379 self
.assertEqual(1+6j
,complex(repr(1+6j
)))
380 self
.assertEqual(-6j
,complex(repr(-6j
)))
381 self
.assertEqual(6j
,complex(repr(6j
)))
383 self
.assertEqual(repr(complex(1., INF
)), "(1+infj)")
384 self
.assertEqual(repr(complex(1., -INF
)), "(1-infj)")
385 self
.assertEqual(repr(complex(INF
, 1)), "(inf+1j)")
386 self
.assertEqual(repr(complex(-INF
, INF
)), "(-inf+infj)")
387 self
.assertEqual(repr(complex(NAN
, 1)), "(nan+1j)")
388 self
.assertEqual(repr(complex(1, NAN
)), "(1+nanj)")
389 self
.assertEqual(repr(complex(NAN
, NAN
)), "(nan+nanj)")
391 self
.assertEqual(repr(complex(0, INF
)), "infj")
392 self
.assertEqual(repr(complex(0, -INF
)), "-infj")
393 self
.assertEqual(repr(complex(0, NAN
)), "nanj")
396 self
.assertEqual(-(1+6j
), -1-6j
)
404 fo
= open(test_support
.TESTFN
, "wb")
407 fo
= open(test_support
.TESTFN
, "rb")
408 self
.assertEqual(fo
.read(), "%s %s\n" % (a
, b
))
410 if (fo
is not None) and (not fo
.closed
):
413 os
.remove(test_support
.TESTFN
)
414 except (OSError, IOError):
417 def test_getnewargs(self
):
418 self
.assertEqual((1+2j
).__getnewargs
__(), (1.0, 2.0))
419 self
.assertEqual((1-2j
).__getnewargs
__(), (1.0, -2.0))
420 self
.assertEqual((2j
).__getnewargs
__(), (0.0, 2.0))
421 self
.assertEqual((-0j
).__getnewargs
__(), (0.0, -0.0))
422 self
.assertEqual(complex(0, INF
).__getnewargs
__(), (0.0, INF
))
423 self
.assertEqual(complex(INF
, 0).__getnewargs
__(), (INF
, 0.0))
425 if float.__getformat
__("double").startswith("IEEE"):
426 def test_plus_minus_0j(self
):
427 # test that -0j and 0j literals are not identified
429 self
.assertEquals(atan2(z1
.imag
, -1.), atan2(0., -1.))
430 self
.assertEquals(atan2(z2
.imag
, -1.), atan2(-0., -1.))
432 @unittest.skipUnless(float.__getformat
__("double").startswith("IEEE"),
433 "test requires IEEE 754 doubles")
434 def test_repr_roundtrip(self
):
435 # complex(repr(z)) should recover z exactly, even for complex numbers
436 # involving an infinity, nan, or negative zero
437 vals
= [0.0, 1e-200, 0.0123, 3.1415, 1e50
, INF
, NAN
]
438 vals
+= [-v
for v
in vals
]
442 roundtrip
= complex(repr(z
))
443 self
.assertFloatsAreIdentical(z
.real
, roundtrip
.real
)
444 self
.assertFloatsAreIdentical(z
.imag
, roundtrip
.imag
)
448 test_support
.run_unittest(ComplexTest
)
450 if __name__
== "__main__":