assert_eq_float/
ne.rs

1/// Asserts that two float expressions are not (approximately) equal to each other.
2///
3/// On panic, this macro will print the values of the expressions with their
4/// debug representations.
5///
6/// Like [`assert_ne!`], this macro has a second form, where a custom
7/// panic message can be provided.
8///
9/// # Examples
10///
11/// ```rust
12/// use assert_eq_float::assert_ne_float;
13///
14/// let a = 3.01;
15/// let b = 1.0 + 2.0;
16///
17/// assert_ne_float!(a, b);
18///
19/// assert_ne_float!(a, b; "we are testing addition with {} and {}", a, b);
20///
21/// assert_ne_float!(a, b, 1e-7); // use a fixed error
22/// ```
23///
24/// Note that when setting a custom panic message, you should use a semicolon `;` instead of a comma `,`.
25#[macro_export]
26macro_rules! assert_ne_float {
27    (@standard $left:ident, $right:ident, $error:ident) => {
28        {
29            use $crate::num_traits::float::FloatCore;
30
31            let d_abs = ($left - $right).abs();
32
33            if $left == $right || d_abs < $error {
34                panic!(
35                    "assertion failed: `(left != right)`\n  left: `{:?}`,\n right: `{:?}`\n  diff: `{:?}`\n error: `{:?}`",
36                    $left,
37                    $right,
38                    d_abs,
39                    $error,
40                );
41            }
42        }
43    };
44    (@custom $left:ident, $right:ident, $error:ident; $($arg:tt)+) => {
45        if $left == $right {
46            panic!($($arg)+);
47        }
48
49        {
50            use $crate::num_traits::float::FloatCore;
51
52            let d_abs = ($left - $right).abs();
53
54            assert!(
55                d_abs >= $error,
56                $($arg)+
57            );
58        }
59    };
60    ($left:expr, $right:expr $(,)?) => {{
61        let left = $left;
62        let right = $right;
63        let error = $crate::get_error(left, right);
64
65        $crate::assert_ne_float!(@standard left, right, error);
66    }};
67    ($left:expr, $right:expr; $($arg:tt)+) => {{
68        let left = $left;
69        let right = $right;
70        let error = $crate::get_error(left, right);
71
72        $crate::assert_ne_float!(@custom left, right, error; $($arg)+);
73    }};
74    ($left:expr, $right:expr, $error:expr $(,)?) => {{
75        let left = $left;
76        let right = $right;
77        let error = $error;
78
79        $crate::assert_ne_float!(@standard left, right, error);
80    }};
81    ($left:expr, $right:expr, $error:expr; $($arg:tt)+) => {{
82        let left = $left;
83        let right = $right;
84        let error = $error;
85
86        $crate::assert_ne_float!(@custom left, right, error; $($arg)+);
87    }};
88}
89
90/// Asserts that two float expressions are not (approximately) equal to each other.
91///
92/// Unlike [`assert_ne_float!`], `debug_assert_ne_float!` statements are only enabled in non
93/// optimized builds by default. An optimized build will not execute
94/// `debug_assert_ne_float!` statements unless `-C debug-assertions` is passed to the
95/// compiler. This makes `debug_assert_ne_float!` useful for checks that are too
96/// expensive to be present in a release build but may be helpful during
97/// development. The result of expanding `debug_assert_ne_float!` is always type checked.
98#[macro_export]
99macro_rules! debug_assert_ne_float {
100    ($left:expr, $right:expr $(,)?) => {
101        #[cfg(debug_assertions)]
102        $crate::assert_ne_float!($left, $right);
103    };
104    ($left:expr, $right:expr; $($arg:tt)+) => {
105        #[cfg(debug_assertions)]
106        $crate::assert_ne_float!($left, $right; $($arg)+);
107    };
108    ($left:expr, $right:expr, $error:expr $(,)?) => {
109        #[cfg(debug_assertions)]
110        $crate::assert_ne_float!($left, $right, $error);
111    };
112    ($left:expr, $right:expr, $error:expr; $($arg:tt)+) => {
113        #[cfg(debug_assertions)]
114        $crate::assert_ne_float!($left, $right, $error; $($arg)+);
115    };
116}