@@ -1840,6 +1840,35 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
1840
1840
/// assert!(abs_difference < 1e-10);
1841
1841
/// ```
1842
1842
fn integer_decode ( self ) -> ( u64 , i16 , i8 ) ;
1843
+
1844
+ /// Returns a number composed of the magnitude of `self` and the sign of
1845
+ /// `sign`.
1846
+ ///
1847
+ /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
1848
+ /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of
1849
+ /// `sign` is returned.
1850
+ ///
1851
+ /// # Examples
1852
+ ///
1853
+ /// ```
1854
+ /// use num_traits::Float;
1855
+ ///
1856
+ /// let f = 3.5_f32;
1857
+ ///
1858
+ /// assert_eq!(f.copysign(0.42), 3.5_f32);
1859
+ /// assert_eq!(f.copysign(-0.42), -3.5_f32);
1860
+ /// assert_eq!((-f).copysign(0.42), 3.5_f32);
1861
+ /// assert_eq!((-f).copysign(-0.42), -3.5_f32);
1862
+ ///
1863
+ /// assert!(f32::nan().copysign(1.0).is_nan());
1864
+ /// ```
1865
+ fn copysign ( self , sign : Self ) -> Self {
1866
+ if self . is_sign_negative ( ) == sign. is_sign_negative ( ) {
1867
+ self
1868
+ } else {
1869
+ self . neg ( )
1870
+ }
1871
+ }
1843
1872
}
1844
1873
1845
1874
#[ cfg( feature = "std" ) ]
@@ -1916,6 +1945,7 @@ macro_rules! float_impl_std {
1916
1945
Self :: asinh( self ) -> Self ;
1917
1946
Self :: acosh( self ) -> Self ;
1918
1947
Self :: atanh( self ) -> Self ;
1948
+ Self :: copysign( self , sign: Self ) -> Self ;
1919
1949
}
1920
1950
}
1921
1951
} ;
@@ -2095,6 +2125,7 @@ impl Float for f64 {
2095
2125
libm:: atanh as atanh( self ) -> Self ;
2096
2126
libm:: fmax as max( self , other: Self ) -> Self ;
2097
2127
libm:: fmin as min( self , other: Self ) -> Self ;
2128
+ libm:: copysign as copysign( self , sign: Self ) -> Self ;
2098
2129
}
2099
2130
}
2100
2131
@@ -2243,4 +2274,28 @@ mod tests {
2243
2274
check :: < f32 > ( 1e-6 ) ;
2244
2275
check :: < f64 > ( 1e-12 ) ;
2245
2276
}
2277
+
2278
+ #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2279
+ #[ test]
2280
+ fn copysign ( ) {
2281
+ use float:: Float ;
2282
+ test_copysign_generic ( 2.0_f32 , -2.0_f32 , f32:: nan ( ) ) ;
2283
+ test_copysign_generic ( 2.0_f64 , -2.0_f64 , f64:: nan ( ) ) ;
2284
+ }
2285
+
2286
+ #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2287
+ fn test_copysign_generic < F : :: float:: Float + core:: fmt:: Debug > ( p : F , n : F , nan : F ) {
2288
+ assert ! ( p. is_sign_positive( ) ) ;
2289
+ assert ! ( n. is_sign_negative( ) ) ;
2290
+ assert ! ( nan. is_nan( ) ) ;
2291
+
2292
+ assert_eq ! ( p, p. copysign( p) ) ;
2293
+ assert_eq ! ( p. neg( ) , p. copysign( n) ) ;
2294
+
2295
+ assert_eq ! ( n, n. copysign( n) ) ;
2296
+ assert_eq ! ( n. neg( ) , n. copysign( p) ) ;
2297
+
2298
+ assert ! ( nan. copysign( p) . is_sign_positive( ) ) ;
2299
+ assert ! ( nan. copysign( n) . is_sign_negative( ) ) ;
2300
+ }
2246
2301
}
0 commit comments