float_cmp/
macros.rs

1
2#[macro_export]
3macro_rules! approx_eq {
4    ($typ:ty, $lhs:expr, $rhs:expr) => {
5        {
6            let m: <$typ as $crate::ApproxEq>::Margin = Default::default();
7            <$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, m)
8        }
9    };
10    ($typ:ty, $lhs:expr, $rhs:expr $(, $set:ident = $val:expr)*) => {
11        {
12            let m = <$typ as $crate::ApproxEq>::Margin::zero()$(.$set($val))*;
13            <$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, m)
14        }
15    };
16    ($typ:ty, $lhs:expr, $rhs:expr, $marg:expr) => {
17        {
18            <$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, $marg)
19        }
20    };
21}
22
23// Until saturating_abs() comes out of nightly, we have to code it ourselves.
24macro_rules! saturating_abs_i32 {
25    ($val:expr) => {
26        if $val.is_negative() {
27            match $val.checked_neg() {
28                Some(v) => v,
29                None => core::i32::MAX
30            }
31        } else {
32            $val
33        }
34    };
35}
36macro_rules! saturating_abs_i64 {
37    ($val:expr) => {
38        if $val.is_negative() {
39            match $val.checked_neg() {
40                Some(v) => v,
41                None => core::i64::MAX
42            }
43        } else {
44            $val
45        }
46    };
47}
48
49#[test]
50fn test_macro() {
51    let a: f32 = 0.15 + 0.15 + 0.15;
52    let b: f32 = 0.1 + 0.1 + 0.25;
53    assert!( approx_eq!(f32, a, b) ); // uses the default
54    assert!( approx_eq!(f32, a, b, ulps = 2) );
55    assert!( approx_eq!(f32, a, b, epsilon = 0.00000003) );
56    assert!( approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2) );
57    assert!( approx_eq!(f32, a, b, (0.0, 2)) );
58}
59
60#[test]
61fn test_macro_2() {
62    assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64) );
63    assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, ulps=3) );
64    assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, epsilon=0.0000000004) );
65    assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0000000004, 0)) );
66    assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0, 3)) );
67}
68
69#[test]
70fn test_macro_3() {
71    use crate::F32Margin;
72
73    let a: f32 = 0.15 + 0.15 + 0.15;
74    let b: f32 = 0.1 + 0.1 + 0.25;
75    assert!( approx_eq!(f32, a, b, F32Margin { epsilon: 0.0, ulps: 2 }) );
76    assert!( approx_eq!(f32, a, b, F32Margin::default()) );
77}