Skip to content

Commit 2a6a7cb

Browse files
committed
gh-156695: Improve accuracy of complex powers with small negative integer exponents
1 parent f74cdf8 commit 2a6a7cb

2 files changed

Lines changed: 17 additions & 3 deletions

File tree

Lib/test/test_complex.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
)
99

1010
from random import random
11-
from math import isnan, copysign
11+
from math import isnan, copysign, ulp
1212
import operator
1313

1414
INF = float("inf")
@@ -446,6 +446,20 @@ def test_pow_with_small_integer_exponents(self):
446446
self.assertEqual(str(float_pow), str(int_pow))
447447
self.assertEqual(str(complex_pow), str(int_pow))
448448

449+
@support.requires_IEEE_754
450+
def test_pow_small_negative_integer_exponents(self):
451+
z = complex(float.fromhex('0x1.47e9c711723f5p+81'),
452+
float.fromhex('0x1.38afd1168e49fp+85'))
453+
expected = complex(float.fromhex('0x0.4000000000000p-1022'),
454+
float.fromhex('0x0.3ffffffffffffp-1022'))
455+
for exponent in (-12, -12.0, complex(-12.0, 0.0)):
456+
with self.subTest(exponent=exponent):
457+
result = z ** exponent
458+
self.assertLessEqual(abs(result.real - expected.real),
459+
4 * ulp(expected.real))
460+
self.assertLessEqual(abs(result.imag - expected.imag),
461+
4 * ulp(expected.imag))
462+
449463
def test_boolcontext(self):
450464
for i in range(100):
451465
self.assertTrue(complex(random() + 1e-6, random() + 1e-6))

Objects/complexobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,10 @@ c_powu(Py_complex x, long n)
357357
static Py_complex
358358
c_powi(Py_complex x, long n)
359359
{
360-
if (n > 0)
360+
if (n >= 0)
361361
return c_powu(x,n);
362362
else
363-
return _Py_c_quot(c_1, c_powu(x,-n));
363+
return c_powu(_Py_c_quot(c_1, x), -n);
364364

365365
}
366366

0 commit comments

Comments
 (0)