Skip to content

Commit 6fb1d12

Browse files
committed
Use _Py_c_pow() to test implementation
1 parent 8e0c482 commit 6fb1d12

1 file changed

Lines changed: 27 additions & 13 deletions

File tree

Lib/test/test_complex.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
from random import random
88
from math import atan2, isnan, copysign
9-
from cmath import log, exp, isclose, isnan as cisnan
109
from functools import reduce
1110
from itertools import combinations
1211
import operator
12+
import _testcapi
1313

1414
INF = float("inf")
1515
NAN = float("nan")
@@ -345,18 +345,32 @@ def test_pow_with_small_integer_exponents(self):
345345
except OverflowError:
346346
continue
347347
r_pro = reduce(lambda x, y: x*y, [z]*e) if e else 1+0j
348-
test = str(r_pow) == str(r_pro)
349-
if not test:
350-
# We might fail here, because associativity of multiplication
351-
# is broken already for floats.
352-
# Consider z = 1-1j. Then z*z*z*z = ((z*z)*z)*z = -4+0j,
353-
# while in the algorithm for pow() a diffenent grouping
354-
# of operations is used: z**4 = (z*z)*(z*z) = -4-0j.
355-
r_pro = exp(e*log(z))
356-
self.assertTrue(test or isclose(r_pow, r_pro))
357-
if not cisnan(r_pow):
358-
self.assertEqual(copysign(1, r_pow.real), copysign(1, r_pro.real))
359-
self.assertEqual(copysign(1, r_pow.imag), copysign(1, r_pro.imag))
348+
if str(r_pow) == str(r_pro):
349+
continue
350+
351+
self.assertNotIn(z.real, {0.0, -0.0, INF, -INF, NAN})
352+
self.assertNotIn(z.imag, {0.0, -0.0, INF, -INF, NAN})
353+
354+
# We might fail here, because associativity of multiplication
355+
# is broken already for floats.
356+
# Consider z = 1-1j. Then z*z*z*z = ((z*z)*z)*z = -4+0j,
357+
# while in the algorithm for pow() a diffenent grouping
358+
# of operations is used: z**4 = (z*z)*(z*z) = -4-0j.
359+
#
360+
# Fallback to the generic complex power algorithm.
361+
r_pro, r_pro_errno = _testcapi._py_c_pow(z, e)
362+
self.assertEqual(r_pro_errno, 0)
363+
self.assertClose(r_pow, r_pro)
364+
if not isnan(r_pow.real):
365+
self.assertEqual(copysign(1, r_pow.real),
366+
copysign(1, r_pro.real))
367+
else:
368+
self.assertTrue(isnan(r_pro.real))
369+
if not isnan(r_pow.imag):
370+
self.assertEqual(copysign(1, r_pow.imag),
371+
copysign(1, r_pro.imag))
372+
else:
373+
self.assertTrue(isnan(r_pro.imag))
360374

361375
def test_boolcontext(self):
362376
for i in range(100):

0 commit comments

Comments
 (0)