@@ -1577,6 +1577,23 @@ mod test {
1577
1577
pub const _05_05i: Complex64 = Complex { re : 0.5 , im : 0.5 } ;
1578
1578
pub const all_consts: [ Complex64 ; 5 ] = [ _0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i] ;
1579
1579
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 } ;
1580
1597
1581
1598
#[ test]
1582
1599
fn test_consts ( ) {
@@ -1727,6 +1744,50 @@ mod test {
1727
1744
close
1728
1745
}
1729
1746
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
+
1730
1791
#[ test]
1731
1792
fn test_exp ( ) {
1732
1793
assert ! ( close( _1_0i. exp( ) , _1_0i. scale( f64 :: consts:: E ) ) ) ;
@@ -1746,6 +1807,24 @@ mod test {
1746
1807
( c + _0_1i. scale( f64 :: consts:: PI * 2.0 ) ) . exp( )
1747
1808
) ) ;
1748
1809
}
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) ) ;
1749
1828
}
1750
1829
1751
1830
#[ test]
0 commit comments