@@ -342,6 +342,9 @@ impl<T: Float> Complex<T> {
342342 /// Raises `self` to a floating point power.
343343 #[ inline]
344344 pub fn powf ( self , exp : T ) -> Self {
345+ if exp. is_zero ( ) {
346+ return Self :: one ( ) ;
347+ }
345348 // formula: x^y = (ρ e^(i θ))^y = ρ^y e^(i θ y)
346349 // = from_polar(ρ^y, θ y)
347350 let ( r, theta) = self . to_polar ( ) ;
@@ -361,22 +364,11 @@ impl<T: Float> Complex<T> {
361364 /// Raises `self` to a complex power.
362365 #[ inline]
363366 pub fn powc ( self , exp : Self ) -> Self {
364- // formula: x^y = (a + i b)^(c + i d)
365- // = (ρ e^(i θ))^c (ρ e^(i θ))^(i d)
366- // where ρ=|x| and θ=arg(x)
367- // = ρ^c e^(−d θ) e^(i c θ) ρ^(i d)
368- // = p^c e^(−d θ) (cos(c θ)
369- // + i sin(c θ)) (cos(d ln(ρ)) + i sin(d ln(ρ)))
370- // = p^c e^(−d θ) (
371- // cos(c θ) cos(d ln(ρ)) − sin(c θ) sin(d ln(ρ))
372- // + i(cos(c θ) sin(d ln(ρ)) + sin(c θ) cos(d ln(ρ))))
373- // = p^c e^(−d θ) (cos(c θ + d ln(ρ)) + i sin(c θ + d ln(ρ)))
374- // = from_polar(p^c e^(−d θ), c θ + d ln(ρ))
375- let ( r, theta) = self . to_polar ( ) ;
376- Self :: from_polar (
377- r. powf ( exp. re ) * ( -exp. im * theta) . exp ( ) ,
378- exp. re * theta + exp. im * r. ln ( ) ,
379- )
367+ if exp. is_zero ( ) {
368+ return Self :: one ( ) ;
369+ }
370+ // formula: x^y = exp(y * ln(x))
371+ ( exp * self . ln ( ) ) . exp ( )
380372 }
381373
382374 /// Raises a floating point number to the complex power `self`.
@@ -1715,6 +1707,9 @@ pub(crate) mod test {
17151707
17161708 #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
17171709 pub ( crate ) mod float {
1710+
1711+ use core:: f64:: INFINITY ;
1712+
17181713 use super :: * ;
17191714 use num_traits:: { Float , Pow } ;
17201715
@@ -1908,6 +1903,19 @@ pub(crate) mod test {
19081903 Complex :: new( 1.65826 , -0.33502 ) ,
19091904 1e-5
19101905 ) ) ;
1906+ let z = Complex :: new ( 0.0 , 0.0 ) ;
1907+ assert ! ( close( z. powc( b) , z) ) ;
1908+ assert ! ( z. powc( Complex64 :: new( 0. , INFINITY ) ) . is_nan( ) ) ;
1909+ assert ! ( z. powc( Complex64 :: new( 10. , INFINITY ) ) . is_nan( ) ) ;
1910+ assert ! ( z. powc( Complex64 :: new( INFINITY , INFINITY ) ) . is_nan( ) ) ;
1911+ assert ! ( close( z. powc( Complex64 :: new( INFINITY , 0. ) ) , z) ) ;
1912+ assert ! ( z. powc( Complex64 :: new( -1. , 0. ) ) . re. is_infinite( ) ) ;
1913+ assert ! ( z. powc( Complex64 :: new( -1. , 0. ) ) . im. is_nan( ) ) ;
1914+
1915+ for c in all_consts. iter ( ) {
1916+ assert_eq ! ( c. powc( _0_0i) , _1_0i) ;
1917+ }
1918+ assert_eq ! ( _nan_nani. powc( _0_0i) , _1_0i) ;
19111919 }
19121920
19131921 #[ test]
@@ -1917,6 +1925,11 @@ pub(crate) mod test {
19171925 assert ! ( close_to_tol( c. powf( 3.5 ) , expected, 1e-5 ) ) ;
19181926 assert ! ( close_to_tol( Pow :: pow( c, 3.5_f64 ) , expected, 1e-5 ) ) ;
19191927 assert ! ( close_to_tol( Pow :: pow( c, 3.5_f32 ) , expected, 1e-5 ) ) ;
1928+
1929+ for c in all_consts. iter ( ) {
1930+ assert_eq ! ( c. powf( 0.0 ) , _1_0i) ;
1931+ }
1932+ assert_eq ! ( _nan_nani. powf( 0.0 ) , _1_0i) ;
19201933 }
19211934
19221935 #[ test]
0 commit comments