gh-117999: Fix small integer powers of complex numbers (GH-124243) · python/cpython@d56f7e2

GitHub

@@ -84,6 +84,10 @@ def assertClose(self, x, y, eps=1e-9):

8484# check that relative difference < eps

8585self.assertTrue(abs(x-y)/abs(y) <eps)

868687+defassertSameSign(self, x, y):

88+ifcopysign(1., x) !=copysign(1., y):

89+self.fail(f'{x!r} and {y!r} have different signs')

90+8791defcheck_div(self, x, y):

8892"""Compute complex z=x*y, and check that z/x==y and z/y==x."""

8993z=x*y

@@ -446,6 +450,63 @@ def test_pow_with_small_integer_exponents(self):

446450self.assertEqual(str(float_pow), str(int_pow))

447451self.assertEqual(str(complex_pow), str(int_pow))

448452453+# Check that complex numbers with special components

454+# are correctly handled.

455+values= [complex(x, y)

456+forxin [5, -5, +0.0, -0.0, INF, -INF, NAN]

457+foryin [12, -12, +0.0, -0.0, INF, -INF, NAN]]

458+forcinvalues:

459+withself.subTest(value=c):

460+self.assertComplexesAreIdentical(c**0, complex(1, +0.0))

461+self.assertComplexesAreIdentical(c**1, c)

462+self.assertComplexesAreIdentical(c**2, c*c)

463+self.assertComplexesAreIdentical(c**3, c*(c*c))

464+self.assertComplexesAreIdentical(c**3, (c*c)*c)

465+ifnotc:

466+continue

467+forninrange(1, 9):

468+withself.subTest(exponent=-n):

469+self.assertComplexesAreIdentical(c**-n, 1/(c**n))

470+471+# Special cases for complex division.

472+forxin [+2, -2]:

473+foryin [+0.0, -0.0]:

474+c=complex(x, y)

475+withself.subTest(value=c):

476+self.assertComplexesAreIdentical(c**-1, complex(1/x, -y))

477+c=complex(y, x)

478+withself.subTest(value=c):

479+self.assertComplexesAreIdentical(c**-1, complex(y, -1/x))

480+forxin [+INF, -INF]:

481+foryin [+1, -1]:

482+c=complex(x, y)

483+withself.subTest(value=c):

484+self.assertComplexesAreIdentical(c**-1, complex(1/x, -0.0*y))

485+self.assertComplexesAreIdentical(c**-2, complex(0.0, -y/x))

486+c=complex(y, x)

487+withself.subTest(value=c):

488+self.assertComplexesAreIdentical(c**-1, complex(+0.0*y, -1/x))

489+self.assertComplexesAreIdentical(c**-2, complex(-0.0, -y/x))

490+491+# Test that zeroes has the same sign as small non-zero values.

492+eps=1e-11

493+pairs= [(complex(x, y), complex(x, copysign(0.0, y)))

494+forxin [+1, -1] foryin [+eps, -eps]]

495+pairs+= [(complex(y, x), complex(copysign(0.0, y), x))

496+forxin [+1, -1] foryin [+eps, -eps]]

497+forc1, c2inpairs:

498+forninexponents:

499+withself.subTest(value=c1, exponent=n):

500+r1=c1**n

501+r2=c2**n

502+self.assertClose(r1, r2)

503+self.assertSameSign(r1.real, r2.real)

504+self.assertSameSign(r1.imag, r2.imag)

505+self.assertNotEqual(r1.real, 0.0)

506+ifn!=0:

507+self.assertNotEqual(r1.imag, 0.0)

508+self.assertTrue(r2.real==0.0orr2.imag==0.0)

509+449510deftest_boolcontext(self):

450511foriinrange(100):

451512self.assertTrue(complex(random() +1e-6, random() +1e-6))