Skip to content

Commit 2766b77

Browse files
committed
make the default float comparison tolerance type-dependent
1 parent 79cb013 commit 2766b77

File tree

1 file changed

+31
-15
lines changed
  • library/coretests/tests/floats

1 file changed

+31
-15
lines changed

library/coretests/tests/floats/mod.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
11
use std::fmt;
22
use std::ops::{Add, Div, Mul, Rem, Sub};
33

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.
528
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)) }};
730
($a:expr, $b:expr, $lim:expr) => {{
831
let (a, b) = (&$a, &$b);
932
let diff = (*a - *b).abs();
@@ -57,15 +80,6 @@ pub(crate) use assert_biteq_ as assert_biteq;
5780
mod const_asserts {
5881
// Shadow some assert implementations that would otherwise not compile in a const-context.
5982
// Every macro added here also needs to be added in the `float_test!` macro below.
60-
macro_rules! assert_eq {
61-
($left:expr, $right:expr $(,)?) => {
62-
std::assert!($left == $right)
63-
};
64-
($left:expr, $right:expr, $($arg:tt)+) => {
65-
std::assert!($left == $right, $($arg)+)
66-
};
67-
}
68-
pub(crate) use assert_eq;
6983

7084
macro_rules! assert_biteq {
7185
(@inner $left:expr, $right:expr, $msg_sep:literal, $($tt:tt)*) => {{
@@ -94,7 +108,7 @@ mod const_asserts {
94108
pub(crate) use assert_biteq;
95109

96110
macro_rules! assert_approx_eq {
97-
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
111+
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, $crate::floats::lim_for_ty($a)) }};
98112
($a:expr, $b:expr, $lim:expr) => {{
99113
let (a, b) = (&$a, &$b);
100114
let diff = (*a - *b).abs();
@@ -171,7 +185,9 @@ macro_rules! float_test {
171185
$( $( #[$const_meta] )+ )?
172186
mod const_ {
173187
#[allow(unused)]
174-
use $crate::floats::const_asserts::{assert_eq, assert_biteq, assert_approx_eq};
188+
use super::Approx;
189+
#[allow(unused)]
190+
use $crate::floats::const_asserts::{assert_biteq, assert_approx_eq};
175191

176192
#[test]
177193
$( $( #[$f16_const_meta] )+ )?
@@ -650,15 +666,15 @@ float_test! {
650666
},
651667
test<Float> {
652668
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
669+
assert_approx_eq!((1.3 as Float).fract(), 0.3); // rounding differs between float types
654670
assert_biteq!((1.5 as Float).fract(), 0.5);
655671
assert_approx_eq!((1.7 as Float).fract(), 0.7);
656672
assert_biteq!((0.5 as Float).fract(), 0.5);
657673
assert_biteq!((0.0 as Float).fract(), 0.0);
658674
assert_biteq!((-0.0 as Float).fract(), 0.0);
659675
assert_biteq!((-0.5 as Float).fract(), -0.5);
660676
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
677+
assert_approx_eq!((-1.3 as Float).fract(), -0.3); // rounding differs between float types
662678
assert_biteq!((-1.5 as Float).fract(), -0.5);
663679
assert_approx_eq!((-1.7 as Float).fract(), -0.7);
664680
assert_biteq!(Float::MAX.fract(), 0.0);

0 commit comments

Comments
 (0)