@@ -1577,6 +1577,23 @@ mod test {
15771577 pub const _05_05i: Complex64 = Complex { re : 0.5 , im : 0.5 } ;
15781578 pub const all_consts: [ Complex64 ; 5 ] = [ _0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i] ;
15791579 pub const _4_2i: Complex64 = Complex { re : 4.0 , im : 2.0 } ;
1580+ pub const _1_infi: Complex64 = Complex { re : 1.0 , im : f64:: INFINITY } ;
1581+ pub const _neg1_infi: Complex64 = Complex { re : -1.0 , im : f64:: INFINITY } ;
1582+ pub const _1_nani: Complex64 = Complex { re : 1.0 , im : f64:: NAN } ;
1583+ pub const _neg1_nani: Complex64 = Complex { re : -1.0 , im : f64:: NAN } ;
1584+ pub const _inf_0i: Complex64 = Complex { re : f64:: INFINITY , im : 0.0 } ;
1585+ pub const _neginf_1i: Complex64 = Complex { re : f64:: NEG_INFINITY , im : 1.0 } ;
1586+ pub const _neginf_neg1i: Complex64 = Complex { re : f64:: NEG_INFINITY , im : -1.0 } ;
1587+ pub const _inf_1i: Complex64 = Complex { re : f64:: INFINITY , im : 1.0 } ;
1588+ pub const _inf_neg1i: Complex64 = Complex { re : f64:: INFINITY , im : -1.0 } ;
1589+ pub const _neginf_infi: Complex64 = Complex { re : f64:: NEG_INFINITY , im : f64:: INFINITY } ;
1590+ pub const _inf_infi: Complex64 = Complex { re : f64:: INFINITY , im : f64:: INFINITY } ;
1591+ pub const _neginf_nani: Complex64 = Complex { re : f64:: NEG_INFINITY , im : f64:: NAN } ;
1592+ pub const _inf_nani: Complex64 = Complex { re : f64:: INFINITY , im : f64:: NAN } ;
1593+ pub const _nan_0i: Complex64 = Complex { re : f64:: NAN , im : 0.0 } ;
1594+ pub const _nan_1i: Complex64 = Complex { re : f64:: NAN , im : 1.0 } ;
1595+ pub const _nan_neg1i: Complex64 = Complex { re : f64:: NAN , im : -1.0 } ;
1596+ pub const _nan_nani: Complex64 = Complex { re : f64:: NAN , im : f64:: NAN } ;
15801597
15811598 #[ test]
15821599 fn test_consts ( ) {
@@ -1727,6 +1744,50 @@ mod test {
17271744 close
17281745 }
17291746
1747+
1748+ // Version that also works if re or im are +inf, -inf, or nan
1749+ fn close_naninf ( a : Complex64 , b : Complex64 ) -> bool {
1750+ close_naninf_to_tol ( a, b, 1.0e-10 )
1751+ }
1752+
1753+
1754+ fn close_naninf_to_tol ( a : Complex64 , b : Complex64 , tol : f64 ) -> bool {
1755+
1756+ let mut close = true ;
1757+
1758+ // Compare the real parts
1759+ if a. re . is_finite ( ) {
1760+ if b. re . is_finite ( ) {
1761+ close = ( a. re == b. re ) || ( a. re - b. re ) . abs ( ) < tol;
1762+ } else {
1763+ close = false ;
1764+ }
1765+ } else if ( a. re . is_nan ( ) && !b. re . is_nan ( ) )
1766+ || ( a. re . is_infinite ( ) && a. re . is_sign_positive ( ) && !( b. re . is_infinite ( ) && b. re . is_sign_positive ( ) ) )
1767+ || ( a. re . is_infinite ( ) && a. re . is_sign_negative ( ) && !( b. re . is_infinite ( ) && b. re . is_sign_negative ( ) ) ) {
1768+ close = false ;
1769+ }
1770+
1771+ // Compare the imaginary parts
1772+ if a. im . is_finite ( ) {
1773+ if b. im . is_finite ( ) {
1774+ close = ( a. im == b. im ) || ( a. im - b. im ) . abs ( ) < tol;
1775+ } else {
1776+ close = false ;
1777+ }
1778+ } else if ( a. im . is_nan ( ) && !b. im . is_nan ( ) )
1779+ || ( a. im . is_infinite ( ) && a. im . is_sign_positive ( ) && !( b. im . is_infinite ( ) && b. im . is_sign_positive ( ) ) )
1780+ || ( a. im . is_infinite ( ) && a. im . is_sign_negative ( ) && !( b. im . is_infinite ( ) && b. im . is_sign_negative ( ) ) ) {
1781+ close = false ;
1782+ }
1783+
1784+ if close == false {
1785+ println ! ( "{:?} != {:?}" , a, b) ;
1786+ }
1787+ close
1788+ }
1789+
1790+
17301791 #[ test]
17311792 fn test_exp ( ) {
17321793 assert ! ( close( _1_0i. exp( ) , _1_0i. scale( f64 :: consts:: E ) ) ) ;
@@ -1746,6 +1807,24 @@ mod test {
17461807 ( c + _0_1i. scale( f64 :: consts:: PI * 2.0 ) ) . exp( )
17471808 ) ) ;
17481809 }
1810+
1811+ assert ! ( close_naninf( _1_infi. exp( ) , _nan_nani) ) ;
1812+ assert ! ( close_naninf( _neg1_infi. exp( ) , _nan_nani) ) ;
1813+ assert ! ( close_naninf( _1_nani. exp( ) , _nan_nani) ) ;
1814+ assert ! ( close_naninf( _neg1_nani. exp( ) , _nan_nani) ) ;
1815+ assert ! ( close_naninf( _inf_0i. exp( ) , _inf_0i) ) ;
1816+ assert ! ( close_naninf( _neginf_1i. exp( ) , 0.0 * Complex64 :: new( 1.0 . cos( ) , 1.0 . sin( ) ) ) ) ;
1817+ assert ! ( close_naninf( _neginf_neg1i. exp( ) , 0.0 * Complex64 :: new( ( -1.0 ) . cos( ) , ( -1.0 ) . sin( ) ) ) ) ;
1818+ assert ! ( close_naninf( _inf_1i. exp( ) , f64 :: INFINITY * Complex64 :: new( 1.0 . cos( ) , 1.0 . sin( ) ) ) ) ;
1819+ assert ! ( close_naninf( _inf_neg1i. exp( ) , f64 :: INFINITY * Complex64 :: new( ( -1.0 ) . cos( ) , ( -1.0 ) . sin( ) ) ) ) ;
1820+ assert ! ( close_naninf( _neginf_infi. exp( ) , _0_0i) ) ; // Note: ±0±0i: signs of zeros are unspecified
1821+ assert ! ( close_naninf( _inf_infi. exp( ) , _inf_nani) ) ; // Note: ±∞+NaN*i: sign of the real part is unspecified
1822+ assert ! ( close_naninf( _neginf_nani. exp( ) , _0_0i) ) ; // Note: ±0±0i: signs of zeros are unspecified
1823+ assert ! ( close_naninf( _inf_nani. exp( ) , _inf_nani) ) ; // Note: ±∞+NaN*i: sign of the real part is unspecified
1824+ assert ! ( close_naninf( _nan_0i. exp( ) , _nan_0i) ) ;
1825+ assert ! ( close_naninf( _nan_1i. exp( ) , _nan_nani) ) ;
1826+ assert ! ( close_naninf( _nan_neg1i. exp( ) , _nan_nani) ) ;
1827+ assert ! ( close_naninf( _nan_nani. exp( ) , _nan_nani) ) ;
17491828 }
17501829
17511830 #[ test]
0 commit comments