@@ -165,8 +165,8 @@ _Py_rc_prod(double a, Py_complex b)
165165#ifdef _M_ARM64
166166#pragma optimize("", off)
167167#endif
168- static Py_complex
169- c_quot (Py_complex a , Py_complex b )
168+ Py_complex
169+ _Py_c_quot (Py_complex a , Py_complex b )
170170{
171171 /******************************************************************
172172 This was the original algorithm. It's grossly prone to spurious
@@ -190,14 +190,15 @@ c_quot(Py_complex a, Py_complex b)
190190 * Algorithm 116 (Complex Division, Robert L. Smith, Stanford
191191 * University).
192192 */
193- Py_complex r ; /* the result */
194- const double abs_breal = b .real < 0 ? - b .real : b .real ;
195- const double abs_bimag = b .imag < 0 ? - b .imag : b .imag ;
193+ Py_complex r ; /* the result */
194+ const double abs_breal = b .real < 0 ? - b .real : b .real ;
195+ const double abs_bimag = b .imag < 0 ? - b .imag : b .imag ;
196196
197197 if (abs_breal >= abs_bimag ) {
198198 /* divide tops and bottom by b.real */
199199 if (abs_breal == 0.0 ) {
200- r .real = r .imag = NAN ;
200+ errno = EDOM ;
201+ r .real = r .imag = 0.0 ;
201202 }
202203 else {
203204 const double ratio = b .imag / b .real ;
@@ -297,36 +298,19 @@ _Py_rc_quot(double a, Py_complex b)
297298#endif
298299
299300Py_complex
300- _Py_c_quot (Py_complex a , Py_complex b )
301- {
302- Py_complex r = c_quot (a , b );
303-
304- if (_Py_c_isnan (r ) && _Py_c_iszero (b )) {
305- errno = EDOM ;
306- r .real = r .imag = 0.0 ; /* and set r as documented */
307- }
308- return r ;
309- }
310-
311- static Py_complex
312- c_pow (Py_complex a , Py_complex b )
301+ _Py_c_pow (Py_complex a , Py_complex b )
313302{
314303 Py_complex r ;
315304 double vabs ,len ,at ,phase ;
316-
317- if (_Py_c_iszero (b )) {
305+ if (b .real == 0. && b .imag == 0. ) {
318306 r .real = 1. ;
319307 r .imag = 0. ;
320308 }
321- else if (_Py_c_iszero (a )) {
322- if (b .imag != 0. || b .real < 0. ) {
323- r .real = NAN ;
324- r .imag = NAN ;
325- }
326- else {
327- r .real = 0. ;
328- r .imag = 0. ;
329- }
309+ else if (a .real == 0. && a .imag == 0. ) {
310+ if (b .imag != 0. || b .real < 0. )
311+ errno = EDOM ;
312+ r .real = 0. ;
313+ r .imag = 0. ;
330314 }
331315 else {
332316 vabs = hypot (a .real ,a .imag );
@@ -339,25 +323,10 @@ c_pow(Py_complex a, Py_complex b)
339323 }
340324 r .real = len * cos (phase );
341325 r .imag = len * sin (phase );
342- }
343- return r ;
344- }
345-
346- Py_complex
347- _Py_c_pow (Py_complex a , Py_complex b )
348- {
349- int saved_errno = errno ;
350- Py_complex r = c_pow (a , b );
351326
352- if (_Py_c_isnan (r ) && a .real == 0 && a .imag == 0 ) {
353- errno = EDOM ;
354- r .real = r .imag = 0.0 ; /* and set r as documented */
355- }
356- else if (_Py_c_isinf (r ) && _Py_c_isfinite (a ) && _Py_c_isfinite (b )) {
357- errno = ERANGE ;
358- }
359- else {
360- errno = saved_errno ;
327+ if (_Py_c_isinf (r ) && _Py_c_isfinite (a ) && _Py_c_isfinite (b )) {
328+ errno = ERANGE ;
329+ }
361330 }
362331 return r ;
363332}
@@ -384,7 +353,7 @@ c_powi(Py_complex x, long n)
384353 if (n > 0 )
385354 return c_powu (x ,n );
386355 else
387- return c_quot (c_1 , c_powu (x ,- n ));
356+ return _Py_c_quot (c_1 , c_powu (x ,- n ));
388357
389358}
390359
@@ -772,20 +741,24 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
772741 PyErr_SetString (PyExc_ValueError , "complex modulo" );
773742 return NULL ;
774743 }
744+ errno = 0 ;
775745 // Check whether the exponent has a small integer value, and if so use
776746 // a faster and more accurate algorithm.
777747 if (b .imag == 0.0 && b .real == floor (b .real ) && fabs (b .real ) <= 100.0 ) {
778748 p = c_powi (a , (long )b .real );
749+ if (_Py_c_isinf (p ) && _Py_c_isfinite (a ) && isfinite (b .real )) {
750+ errno = ERANGE ;
751+ }
779752 }
780753 else {
781- p = c_pow (a , b );
754+ p = _Py_c_pow (a , b );
782755 }
783- if (_Py_c_isnan ( p ) && _Py_c_iszero ( a ) && ( b . imag || b . real < 0 ) ) {
756+ if (errno == EDOM ) {
784757 PyErr_SetString (PyExc_ZeroDivisionError ,
785758 "zero to a negative or complex power" );
786759 return NULL ;
787760 }
788- else if (_Py_c_isinf ( p ) && _Py_c_isfinite ( a ) && _Py_c_isfinite ( b ) ) {
761+ else if (errno == ERANGE ) {
789762 PyErr_SetString (PyExc_OverflowError ,
790763 "complex exponentiation" );
791764 return NULL ;
0 commit comments