@@ -241,6 +241,32 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
241
241
self . classify ( ) == FpCategory :: Normal
242
242
}
243
243
244
+ /// Returns `true` if the number is [subnormal].
245
+ ///
246
+ /// ```
247
+ /// use num_traits::float::FloatCore;
248
+ /// use std::f64;
249
+ ///
250
+ /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
251
+ /// let max = f64::MAX;
252
+ /// let lower_than_min = 1.0e-308_f64;
253
+ /// let zero = 0.0_f64;
254
+ ///
255
+ /// assert!(!min.is_subnormal());
256
+ /// assert!(!max.is_subnormal());
257
+ ///
258
+ /// assert!(!zero.is_subnormal());
259
+ /// assert!(!f64::NAN.is_subnormal());
260
+ /// assert!(!f64::INFINITY.is_subnormal());
261
+ /// // Values between `0` and `min` are Subnormal.
262
+ /// assert!(lower_than_min.is_subnormal());
263
+ /// ```
264
+ /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number
265
+ #[ inline]
266
+ fn is_subnormal ( self ) -> bool {
267
+ self . classify ( ) == FpCategory :: Subnormal
268
+ }
269
+
244
270
/// Returns the floating point category of the number. If only one property
245
271
/// is going to be tested, it is generally faster to use the specific
246
272
/// predicate instead.
@@ -918,6 +944,11 @@ impl FloatCore for f64 {
918
944
Self :: to_radians( self ) -> Self ;
919
945
}
920
946
947
+ #[ cfg( has_is_subnormal) ]
948
+ forward ! {
949
+ Self :: is_subnormal( self ) -> bool ;
950
+ }
951
+
921
952
#[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
922
953
forward ! {
923
954
libm:: floor as floor( self ) -> Self ;
@@ -1123,9 +1154,35 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
1123
1154
/// // Values between `0` and `min` are Subnormal.
1124
1155
/// assert!(!lower_than_min.is_normal());
1125
1156
/// ```
1126
- /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
1157
+ /// [subnormal]: http://en.wikipedia.org/wiki/Subnormal_number
1127
1158
fn is_normal ( self ) -> bool ;
1128
1159
1160
+ /// Returns `true` if the number is [subnormal].
1161
+ ///
1162
+ /// ```
1163
+ /// use num_traits::Float;
1164
+ /// use std::f64;
1165
+ ///
1166
+ /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
1167
+ /// let max = f64::MAX;
1168
+ /// let lower_than_min = 1.0e-308_f64;
1169
+ /// let zero = 0.0_f64;
1170
+ ///
1171
+ /// assert!(!min.is_subnormal());
1172
+ /// assert!(!max.is_subnormal());
1173
+ ///
1174
+ /// assert!(!zero.is_subnormal());
1175
+ /// assert!(!f64::NAN.is_subnormal());
1176
+ /// assert!(!f64::INFINITY.is_subnormal());
1177
+ /// // Values between `0` and `min` are Subnormal.
1178
+ /// assert!(lower_than_min.is_subnormal());
1179
+ /// ```
1180
+ /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number
1181
+ #[ inline]
1182
+ fn is_subnormal ( self ) -> bool {
1183
+ self . classify ( ) == FpCategory :: Subnormal
1184
+ }
1185
+
1129
1186
/// Returns the floating point category of the number. If only one property
1130
1187
/// is going to be tested, it is generally faster to use the specific
1131
1188
/// predicate instead.
@@ -1959,9 +2016,13 @@ macro_rules! float_impl_std {
1959
2016
}
1960
2017
1961
2018
#[ cfg( has_copysign) ]
1962
- #[ inline]
1963
- fn copysign( self , sign: Self ) -> Self {
1964
- Self :: copysign( self , sign)
2019
+ forward! {
2020
+ Self :: copysign( self , sign: Self ) -> Self ;
2021
+ }
2022
+
2023
+ #[ cfg( has_is_subnormal) ]
2024
+ forward! {
2025
+ Self :: is_subnormal( self ) -> bool ;
1965
2026
}
1966
2027
}
1967
2028
} ;
@@ -2318,6 +2379,7 @@ mod tests {
2318
2379
assert ! ( p. is_sign_positive( ) ) ;
2319
2380
assert ! ( n. is_sign_negative( ) ) ;
2320
2381
assert ! ( nan. is_nan( ) ) ;
2382
+ assert ! ( !nan. is_subnormal( ) ) ;
2321
2383
2322
2384
assert_eq ! ( p, p. copysign( p) ) ;
2323
2385
assert_eq ! ( p. neg( ) , p. copysign( n) ) ;
@@ -2328,4 +2390,19 @@ mod tests {
2328
2390
assert ! ( nan. copysign( p) . is_sign_positive( ) ) ;
2329
2391
assert ! ( nan. copysign( n) . is_sign_negative( ) ) ;
2330
2392
}
2393
+
2394
+ #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2395
+ fn test_subnormal < F : crate :: float:: Float + :: core:: fmt:: Debug > ( ) {
2396
+ let min_positive = F :: min_positive_value ( ) ;
2397
+ let lower_than_min = min_positive / F :: from ( 2.0f32 ) . unwrap ( ) ;
2398
+ assert ! ( !min_positive. is_subnormal( ) ) ;
2399
+ assert ! ( lower_than_min. is_subnormal( ) ) ;
2400
+ }
2401
+
2402
+ #[ test]
2403
+ #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2404
+ fn subnormal ( ) {
2405
+ test_subnormal :: < f64 > ( ) ;
2406
+ test_subnormal :: < f32 > ( ) ;
2407
+ }
2331
2408
}
0 commit comments