|
1 | 1 | use std::num::FpCategory as Fp;
|
2 | 2 | use std::ops::{Add, Div, Mul, Rem, Sub};
|
3 | 3 |
|
4 |
| -/// Set the default tolerance for float comparison based on the type. |
5 |
| -trait Approx { |
6 |
| - const LIM: Self; |
| 4 | +trait TestableFloat { |
| 5 | + /// Set the default tolerance for float comparison based on the type. |
| 6 | + const APPROX: Self; |
| 7 | + const MIN_POSITIVE_NORMAL: Self; |
| 8 | + const MAX_SUBNORMAL: Self; |
7 | 9 | }
|
8 | 10 |
|
9 |
| -impl Approx for f16 { |
10 |
| - const LIM: Self = 1e-3; |
| 11 | +impl TestableFloat for f16 { |
| 12 | + const APPROX: Self = 1e-3; |
| 13 | + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; |
| 14 | + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); |
11 | 15 | }
|
12 |
| -impl Approx for f32 { |
13 |
| - const LIM: Self = 1e-6; |
| 16 | + |
| 17 | +impl TestableFloat for f32 { |
| 18 | + const APPROX: Self = 1e-6; |
| 19 | + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; |
| 20 | + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); |
14 | 21 | }
|
15 |
| -impl Approx for f64 { |
16 |
| - const LIM: Self = 1e-6; |
| 22 | + |
| 23 | +impl TestableFloat for f64 { |
| 24 | + const APPROX: Self = 1e-6; |
| 25 | + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; |
| 26 | + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); |
17 | 27 | }
|
18 |
| -impl Approx for f128 { |
19 |
| - const LIM: Self = 1e-9; |
| 28 | + |
| 29 | +impl TestableFloat for f128 { |
| 30 | + const APPROX: Self = 1e-9; |
| 31 | + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; |
| 32 | + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); |
20 | 33 | }
|
21 | 34 |
|
22 | 35 | /// Determine the tolerance for values of the argument type.
|
23 |
| -const fn lim_for_ty<T: Approx + Copy>(_x: T) -> T { |
24 |
| - T::LIM |
| 36 | +const fn lim_for_ty<T: TestableFloat + Copy>(_x: T) -> T { |
| 37 | + T::APPROX |
25 | 38 | }
|
26 | 39 |
|
27 | 40 | // We have runtime ("rt") and const versions of these macros.
|
@@ -186,7 +199,7 @@ macro_rules! float_test {
|
186 | 199 | $( $( #[$const_meta] )+ )?
|
187 | 200 | mod const_ {
|
188 | 201 | #[allow(unused)]
|
189 |
| - use super::Approx; |
| 202 | + use super::TestableFloat; |
190 | 203 | #[allow(unused)]
|
191 | 204 | use std::num::FpCategory as Fp;
|
192 | 205 | #[allow(unused)]
|
@@ -446,6 +459,30 @@ float_test! {
|
446 | 459 | }
|
447 | 460 | }
|
448 | 461 |
|
| 462 | +float_test! { |
| 463 | + name: is_normal, |
| 464 | + attrs: { |
| 465 | + f16: #[cfg(any(miri, target_has_reliable_f16))], |
| 466 | + f128: #[cfg(any(miri, target_has_reliable_f128))], |
| 467 | + }, |
| 468 | + test<Float> { |
| 469 | + let nan: Float = Float::NAN; |
| 470 | + let inf: Float = Float::INFINITY; |
| 471 | + let neg_inf: Float = Float::NEG_INFINITY; |
| 472 | + let zero: Float = 0.0; |
| 473 | + let neg_zero: Float = -0.0; |
| 474 | + let one : Float = 1.0; |
| 475 | + assert!(!nan.is_normal()); |
| 476 | + assert!(!inf.is_normal()); |
| 477 | + assert!(!neg_inf.is_normal()); |
| 478 | + assert!(!zero.is_normal()); |
| 479 | + assert!(!neg_zero.is_normal()); |
| 480 | + assert!(one.is_normal()); |
| 481 | + assert!(Float::MIN_POSITIVE_NORMAL.is_normal()); |
| 482 | + assert!(!Float::MAX_SUBNORMAL.is_normal()); |
| 483 | + } |
| 484 | +} |
| 485 | + |
449 | 486 | float_test! {
|
450 | 487 | name: min,
|
451 | 488 | attrs: {
|
|
0 commit comments