@@ -342,6 +342,9 @@ impl<T: Float> Complex<T> {
342
342
/// Raises `self` to a floating point power.
343
343
#[ inline]
344
344
pub fn powf ( self , exp : T ) -> Self {
345
+ if exp. is_zero ( ) {
346
+ return Self :: one ( ) ;
347
+ }
345
348
// formula: x^y = (ρ e^(i θ))^y = ρ^y e^(i θ y)
346
349
// = from_polar(ρ^y, θ y)
347
350
let ( r, theta) = self . to_polar ( ) ;
@@ -361,22 +364,11 @@ impl<T: Float> Complex<T> {
361
364
/// Raises `self` to a complex power.
362
365
#[ inline]
363
366
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 ( )
380
372
}
381
373
382
374
/// Raises a floating point number to the complex power `self`.
@@ -1715,6 +1707,9 @@ pub(crate) mod test {
1715
1707
1716
1708
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
1717
1709
pub ( crate ) mod float {
1710
+
1711
+ use core:: f64:: INFINITY ;
1712
+
1718
1713
use super :: * ;
1719
1714
use num_traits:: { Float , Pow } ;
1720
1715
@@ -1908,6 +1903,19 @@ pub(crate) mod test {
1908
1903
Complex :: new( 1.65826 , -0.33502 ) ,
1909
1904
1e-5
1910
1905
) ) ;
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) ;
1911
1919
}
1912
1920
1913
1921
#[ test]
@@ -1917,6 +1925,11 @@ pub(crate) mod test {
1917
1925
assert ! ( close_to_tol( c. powf( 3.5 ) , expected, 1e-5 ) ) ;
1918
1926
assert ! ( close_to_tol( Pow :: pow( c, 3.5_f64 ) , expected, 1e-5 ) ) ;
1919
1927
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) ;
1920
1933
}
1921
1934
1922
1935
#[ test]
0 commit comments