|
1 | 1 | use std::fmt;
|
2 | 2 | use std::ops::{Add, Div, Mul, Rem, Sub};
|
3 | 3 |
|
4 |
| -/// Verify that floats are within a tolerance of each other, 1.0e-6 by default. |
| 4 | +/// Set the default tolerance for float comparison based on the type. |
| 5 | +trait Approx { |
| 6 | + const LIM: Self; |
| 7 | +} |
| 8 | + |
| 9 | +impl Approx for f16 { |
| 10 | + const LIM: Self = 1e-3; |
| 11 | +} |
| 12 | +impl Approx for f32 { |
| 13 | + const LIM: Self = 1e-6; |
| 14 | +} |
| 15 | +impl Approx for f64 { |
| 16 | + const LIM: Self = 1e-6; |
| 17 | +} |
| 18 | +impl Approx for f128 { |
| 19 | + const LIM: Self = 1e-9; |
| 20 | +} |
| 21 | + |
| 22 | +/// Determine the tolerance for values of the argument type. |
| 23 | +const fn lim_for_ty<T: Approx + Copy>(_x: T) -> T { |
| 24 | + T::LIM |
| 25 | +} |
| 26 | + |
| 27 | +/// Verify that floats are within a tolerance of each other. |
5 | 28 | macro_rules! assert_approx_eq_ {
|
6 |
| - ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }}; |
| 29 | + ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, $crate::floats::lim_for_ty($a)) }}; |
7 | 30 | ($a:expr, $b:expr, $lim:expr) => {{
|
8 | 31 | let (a, b) = (&$a, &$b);
|
9 | 32 | let diff = (*a - *b).abs();
|
@@ -94,7 +117,7 @@ mod const_asserts {
|
94 | 117 | pub(crate) use assert_biteq;
|
95 | 118 |
|
96 | 119 | macro_rules! assert_approx_eq {
|
97 |
| - ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }}; |
| 120 | + ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, $crate::floats::lim_for_ty($a)) }}; |
98 | 121 | ($a:expr, $b:expr, $lim:expr) => {{
|
99 | 122 | let (a, b) = (&$a, &$b);
|
100 | 123 | let diff = (*a - *b).abs();
|
@@ -170,6 +193,8 @@ macro_rules! float_test {
|
170 | 193 |
|
171 | 194 | $( $( #[$const_meta] )+ )?
|
172 | 195 | mod const_ {
|
| 196 | + #[allow(unused)] |
| 197 | + use super::Approx; |
173 | 198 | #[allow(unused)]
|
174 | 199 | use $crate::floats::const_asserts::{assert_eq, assert_biteq, assert_approx_eq};
|
175 | 200 |
|
@@ -650,15 +675,15 @@ float_test! {
|
650 | 675 | },
|
651 | 676 | test<Float> {
|
652 | 677 | assert_biteq!((1.0 as Float).fract(), 0.0);
|
653 |
| - assert_approx_eq!((1.3 as Float).fract(), 0.3, 1e-3); // rounding differs between float types |
| 678 | + assert_approx_eq!((1.3 as Float).fract(), 0.3); // rounding differs between float types |
654 | 679 | assert_biteq!((1.5 as Float).fract(), 0.5);
|
655 | 680 | assert_approx_eq!((1.7 as Float).fract(), 0.7);
|
656 | 681 | assert_biteq!((0.5 as Float).fract(), 0.5);
|
657 | 682 | assert_biteq!((0.0 as Float).fract(), 0.0);
|
658 | 683 | assert_biteq!((-0.0 as Float).fract(), 0.0);
|
659 | 684 | assert_biteq!((-0.5 as Float).fract(), -0.5);
|
660 | 685 | assert_biteq!((-1.0 as Float).fract(), 0.0);
|
661 |
| - assert_approx_eq!((-1.3 as Float).fract(), -0.3, 1e-3); // rounding differs between float types |
| 686 | + assert_approx_eq!((-1.3 as Float).fract(), -0.3); // rounding differs between float types |
662 | 687 | assert_biteq!((-1.5 as Float).fract(), -0.5);
|
663 | 688 | assert_approx_eq!((-1.7 as Float).fract(), -0.7);
|
664 | 689 | assert_eq!(Float::MAX.fract(), 0.0);
|
|
0 commit comments