assert_float_eq/
lib.rs

1//! Assertions that two floating point numbers are approximately equal.
2//!
3//! Floating-point equality is difficult, and therefore numerous macros
4//! are provided. At the most simple, [`assert_float_absolute_eq`] and
5//! [`assert_float_relative_eq`] assert that the difference between two
6//! floats is smaller than epsilon (default 1e-6) absolutely or
7//! relatively, respectively.
8//!
9//! However, due to the decreasing precision of floating-point numbers
10//! at large values, and the desire for high-stringency, macros to detect
11//! whether a floating point is within a number of "steps" of another
12//! are provided. [`assert_f32_near`] and [`assert_f64_near`] assert whether
13//! an f32 or f64 is within n "steps" (default 4) of another, respectively.
14//! A floating-point step is an increment to the bit-wise pattern of the
15//! float, for example, if a float is represented in-memory as `0x0000FFFF`,
16//! then the next float would be `0x00010000`. This allows float equality
17//! comparisons to floating-point numbers at any precision, simplifying
18//! equality checks for extremely high or low floats without sacrificing
19//! accuracy.
20//!
21//! For example, for a 32-bit float of value `3e37`, each step is `~4e30`,
22//! a gargantuan value (but only a small fraction, ~0.00001% of the total
23//! value).
24//!
25//! In addition to the `assert_*` macros, which panic if the condition
26//! is not true, assert_float_eq also has `expect_*` macros, which
27//! return a `Result<(), T: Display>`, when panicking is not desirable.
28//!
29//! [`assert_float_absolute_eq`]: macro.assert_float_absolute_eq.html
30//! [`assert_float_relative_eq`]: macro.assert_float_relative_eq.html
31//! [`assert_f64_near`]: macro.assert_f64_near.html
32//! [`assert_f32_near`]: macro.assert_f32_near.html
33
34use core::fmt::{Debug, Display, Formatter, Result as FmtResult};
35
36// IMPLEMENTATION
37
38// Make sure we export all functions so they can be visible
39// outside of the crate.
40
41// F32
42
43// IEEE754 CONSTANTS
44// 32 bit floats have the following representation:
45// Sign:        10000000000000000000000000000000
46// Exponent:    01111111100000000000000000000000
47// Hidden:      00000000100000000000000000000000
48// Fraction:    00000000011111111111111111111111
49const U32_SIGN_MASK: u32 = 0x80000000;
50const U32_EXPONENT_MASK: u32 = 0x7F800000;
51const U32_HIDDEN_BIT: u32 = 0x00800000;
52const U32_SIGNIFICAND_MASK: u32 = 0x007FFFFF;
53const U32_INFINITY: u32 = 0x7F800000;
54
55/// Check if value is denormal, has leading zeros in significand.
56#[inline]
57#[doc(hidden)]
58pub fn is_denormal_f32(f: f32) -> bool {
59    let u = f.to_bits();
60    (u & U32_EXPONENT_MASK) == 0
61}
62
63/// Get the sign of a 64-bit float.
64#[inline]
65#[doc(hidden)]
66pub fn sign_f32(f: f32) -> i32 {
67    let u = f.to_bits();
68    if (u & U32_SIGN_MASK) == 0 {
69        1
70    } else {
71        -1
72    }
73}
74
75/// Get the significand of a 32-bit float.
76#[inline]
77#[doc(hidden)]
78pub fn significand_f32(f: f32) -> u32 {
79    let u = f.to_bits();
80    let s = u & U32_SIGNIFICAND_MASK;
81    if is_denormal_f32(f) {
82        s
83    } else {
84        s + U32_HIDDEN_BIT
85    }
86}
87
88/// Get the next 32-bit float.
89#[inline]
90#[doc(hidden)]
91pub fn next_f32(f: f32) -> f32 {
92    let u = f.to_bits();
93    if u == U32_INFINITY {
94        f32::from_bits(U32_INFINITY)
95    } else if sign_f32(f) < 0 && significand_f32(f) == 0 {
96        0.0
97    } else if sign_f32(f) < 0 {
98        f32::from_bits(u - 1)
99    } else {
100        f32::from_bits(u + 1)
101    }
102}
103
104/// Get the next N steps from a 32-bit float.
105#[inline]
106#[doc(hidden)]
107pub fn next_n_f32(mut f: f32, n: u32) -> f32 {
108    for _ in 0..n {
109        f = next_f32(f);
110    }
111    f
112}
113
114/// Get the previous 32-bit float.
115#[inline]
116#[doc(hidden)]
117pub fn previous_f32(f: f32) -> f32 {
118    let u = f.to_bits();
119    if u == (U32_INFINITY | U32_SIGN_MASK) {
120        -f32::from_bits(U32_INFINITY)
121    } else if sign_f32(f) < 0 {
122        f32::from_bits(u + 1)
123    } else if significand_f32(f) == 0 {
124        -0.0
125    } else {
126        f32::from_bits(u - 1)
127    }
128}
129
130/// Get the previous N steps from a 32-bit float.
131#[inline]
132#[doc(hidden)]
133pub fn previous_n_f32(mut f: f32, n: u32) -> f32 {
134    for _ in 0..n {
135        f = previous_f32(f);
136    }
137    f
138}
139
140// F64
141
142// IEEE754 CONSTANTS
143// 64 bit floats have the following representation:
144// Sign:        1000000000000000000000000000000000000000000000000000000000000000
145// Exponent:    0111111111110000000000000000000000000000000000000000000000000000
146// Hidden:      0000000000010000000000000000000000000000000000000000000000000000
147// Significand: 0000000000001111111111111111111111111111111111111111111111111111
148const U64_SIGN_MASK: u64 = 0x8000000000000000;
149const U64_EXPONENT_MASK: u64 = 0x7FF0000000000000;
150const U64_HIDDEN_BIT: u64 = 0x0010000000000000;
151const U64_SIGNIFICAND_MASK: u64 = 0x000FFFFFFFFFFFFF;
152const U64_INFINITY: u64 = 0x7FF0000000000000;
153
154/// Check if value is denormal, has leading zeros in significand.
155#[inline]
156#[doc(hidden)]
157pub fn is_denormal_f64(f: f64) -> bool {
158    let u = f.to_bits();
159    (u & U64_EXPONENT_MASK) == 0
160}
161
162/// Get the sign of a 64-bit float.
163#[inline]
164#[doc(hidden)]
165pub fn sign_f64(f: f64) -> i32 {
166    let u = f.to_bits();
167    if (u & U64_SIGN_MASK) == 0 {
168        1
169    } else {
170        -1
171    }
172}
173
174/// Get the significand of a 64-bit float.
175#[inline]
176#[doc(hidden)]
177pub fn significand_f64(f: f64) -> u64 {
178    let u = f.to_bits();
179    let s = u & U64_SIGNIFICAND_MASK;
180    if is_denormal_f64(f) {
181        s
182    } else {
183        s + U64_HIDDEN_BIT
184    }
185}
186
187/// Get the next 64-bit float.
188#[inline]
189#[doc(hidden)]
190pub fn next_f64(f: f64) -> f64 {
191    let u = f.to_bits();
192    if u == U64_INFINITY {
193        f64::from_bits(U64_INFINITY)
194    } else if sign_f64(f) < 0 && significand_f64(f) == 0 {
195        0.0
196    } else if sign_f64(f) < 0 {
197        f64::from_bits(u - 1)
198    } else {
199        f64::from_bits(u + 1)
200    }
201}
202
203/// Get the next N steps from a 64-bit float.
204#[inline]
205#[doc(hidden)]
206pub fn next_n_f64(mut f: f64, n: u32) -> f64 {
207    for _ in 0..n {
208        f = next_f64(f);
209    }
210    f
211}
212
213/// Get the previous 64-bit float.
214#[inline]
215#[doc(hidden)]
216pub fn previous_f64(f: f64) -> f64 {
217    let u = f.to_bits();
218    if u == (U64_INFINITY | U64_SIGN_MASK) {
219        -f64::from_bits(U64_INFINITY)
220    } else if sign_f64(f) < 0 {
221        f64::from_bits(u + 1)
222    } else if significand_f64(f) == 0 {
223        -0.0
224    } else {
225        f64::from_bits(u - 1)
226    }
227}
228
229/// Get the previous N steps from a 64-bit float.
230#[inline]
231#[doc(hidden)]
232pub fn previous_n_f64(mut f: f64, n: u32) -> f64 {
233    for _ in 0..n {
234        f = previous_f64(f);
235    }
236    f
237}
238
239// GENERAL
240
241/// Message for absolute errors.
242#[macro_export]
243#[doc(hidden)]
244macro_rules! afe_absolute_eq_error_msg {
245    () => {
246        "assertion failed: `|a-b| < epsilon` a: {:?}, b: {:?}, epsilon: {:?}"
247    };
248}
249
250/// Message for absolute errors.
251#[macro_export]
252#[doc(hidden)]
253macro_rules! afe_absolute_ne_error_msg {
254    () => {
255        "assertion failed: `|a-b| >= epsilon` a: {:?}, b: {:?}, epsilon: {:?}"
256    };
257}
258
259/// Message for relative errors.
260#[macro_export]
261#[doc(hidden)]
262macro_rules! afe_relative_eq_error_msg {
263    () => {
264        "assertion failed: `|(a-b) / a| < epsilon` a: {:?}, b: {:?}, epsilon: {:?}"
265    };
266}
267
268/// Message for relative errors.
269#[macro_export]
270#[doc(hidden)]
271macro_rules! afe_relative_ne_error_msg {
272    () => {
273        "assertion failed: `|(a-b) / a| >= epsilon` a: {:?}, b: {:?}, epsilon: {:?}"
274    };
275}
276
277/// Message for near errors.
278#[macro_export]
279#[doc(hidden)]
280macro_rules! afe_near_error_msg {
281    () => ("assertion failed: `b is outside of n steps from a` a: {:?}, b: {:?}, n: {:?}, previous: {:?}, next: {:?}")
282}
283
284/// Message for far errors.
285#[macro_export]
286#[doc(hidden)]
287macro_rules! afe_far_error_msg {
288    () => ("assertion failed: `b is within n steps from a` a: {:?}, b: {:?}, n: {:?}, previous: {:?}, next: {:?}")
289}
290
291/// Generate the classes for the threshold errors.
292#[doc(hidden)]
293macro_rules! threshold_error_impl {
294    ($t:ident, $msg:expr) => {
295        /// Error result for an error threshold.
296        #[derive(Debug)]
297        #[doc(hidden)]
298        pub struct $t<Float: Debug> {
299            a: Float,
300            b: Float,
301            epsilon: Float,
302        }
303
304        impl<Float: Debug> $t<Float> {
305            pub fn new(a: Float, b: Float, epsilon: Float) -> Self {
306                $t {
307                    a,
308                    b,
309                    epsilon,
310                }
311            }
312        }
313
314        impl<Float: Debug> Display for $t<Float> {
315            fn fmt(&self, f: &mut Formatter) -> FmtResult {
316                write!(f, $msg, self.a, self.b, self.epsilon)
317            }
318        }
319    };
320}
321
322threshold_error_impl!(AbsoluteEqError, afe_absolute_eq_error_msg!());
323threshold_error_impl!(AbsoluteNeError, afe_absolute_ne_error_msg!());
324threshold_error_impl!(RelativeEqError, afe_relative_eq_error_msg!());
325threshold_error_impl!(RelativeNeError, afe_relative_ne_error_msg!());
326
327/// Error result for a the `expect_f*_near` methods.
328#[derive(Debug)]
329#[doc(hidden)]
330pub struct FloatNearError<Float: Debug, Int: Debug> {
331    a: Float,
332    b: Float,
333    n: Int,
334    previous: Float,
335    next: Float,
336}
337
338impl<Float: Debug, Int: Debug> FloatNearError<Float, Int> {
339    pub fn new(a: Float, b: Float, n: Int, previous: Float, next: Float) -> Self {
340        Self {
341            a,
342            b,
343            n,
344            previous,
345            next,
346        }
347    }
348}
349
350impl<Float: Debug, Int: Debug> Display for FloatNearError<Float, Int> {
351    fn fmt(&self, f: &mut Formatter) -> FmtResult {
352        write!(f, afe_near_error_msg!(), self.a, self.b, self.n, self.previous, self.next)
353    }
354}
355
356/// Error result for a the `expect_f*_far` methods.
357#[derive(Debug)]
358#[doc(hidden)]
359pub struct FloatFarError<Float: Debug, Int: Debug> {
360    a: Float,
361    b: Float,
362    n: Int,
363    previous: Float,
364    next: Float,
365}
366
367impl<Float: Debug, Int: Debug> FloatFarError<Float, Int> {
368    pub fn new(a: Float, b: Float, n: Int, previous: Float, next: Float) -> Self {
369        Self {
370            a,
371            b,
372            n,
373            previous,
374            next,
375        }
376    }
377}
378
379impl<Float: Debug, Int: Debug> Display for FloatFarError<Float, Int> {
380    fn fmt(&self, f: &mut Formatter) -> FmtResult {
381        write!(f, afe_far_error_msg!(), self.a, self.b, self.n, self.previous, self.next)
382    }
383}
384
385/// Convert a boolean and String to a result.
386#[inline(always)]
387#[doc(hidden)]
388pub fn bool_to_result<T: Display>(r: bool, err: T) -> Result<(), T> {
389    match r {
390        true => Ok(()),
391        false => Err(err),
392    }
393}
394
395/// Maximum implementation.
396///
397/// Don't worry about propagating NaN, for our use-case, any NaN value
398/// will remain after comparison and lead to a diagnostic error.
399#[macro_export]
400#[doc(hidden)]
401macro_rules! afe_max {
402    ($a:expr, $b:expr) => {{
403        let (a, b) = ($a, $b);
404        if a < b {
405            b
406        } else {
407            a
408        }
409    }};
410}
411
412/// Absolute value implementation.
413#[macro_export]
414#[doc(hidden)]
415macro_rules! afe_abs {
416    ($f:expr) => {{
417        let f = $f;
418        if f < 0.0 {
419            -f
420        } else {
421            f
422        }
423    }};
424}
425
426/// Returns true if the values are absolutely equal within a tolerance.
427#[macro_export]
428#[doc(hidden)]
429macro_rules! afe_is_absolute_eq {
430    ($a:ident, $b:ident, $epsilon:ident) => {
431        $crate::afe_abs!($a - $b) <= $epsilon
432    };
433}
434
435/// Returns true if the values are relatively equal within a tolerance.
436#[macro_export]
437#[doc(hidden)]
438macro_rules! afe_is_relative_eq {
439    ($a:ident, $b:ident, $epsilon:ident) => {
440        if $a == 0.0 {
441            $b == 0.0
442        } else {
443            // Only care about the magnitude, not the sign.
444            // NOTE: We can have an unresolved type `{float}` for literals in which case we
445            // only want to check if it's the exact size.
446            let denom = $crate::afe_abs!($a);
447            if (core::mem::size_of_val(&denom) == 4 && (denom as f32).is_nan())
448                || (core::mem::size_of_val(&denom) == 8 && (denom as f64).is_nan())
449            {
450                false
451            } else if (core::mem::size_of_val(&denom) == 4 && (denom as f32).is_infinite())
452                || (core::mem::size_of_val(&denom) == 8 && (denom as f64).is_infinite())
453            {
454                true
455            } else {
456                ($crate::afe_abs!($a - $b) / denom) <= $epsilon
457            }
458        }
459    };
460}
461
462/// Returns true if two 32-bit floats are within n steps of each other.
463#[macro_export]
464#[doc(hidden)]
465macro_rules! afe_is_f32_near {
466    ($a:ident, $b:ident, $n:ident) => {{
467        let previous = $crate::previous_n_f32($a, $n);
468        let next = $crate::next_n_f32($a, $n);
469        let r = $b >= previous && $b <= next;
470        (r, previous, next)
471    }};
472}
473
474/// Returns true if two 64-bit floats are within n steps of each other.
475#[macro_export]
476#[doc(hidden)]
477macro_rules! afe_is_f64_near {
478    ($a:ident, $b:ident, $n:ident) => {{
479        let previous = $crate::previous_n_f64($a, $n);
480        let next = $crate::next_n_f64($a, $n);
481        let r = $b >= previous && $b <= next;
482        (r, previous, next)
483    }};
484}
485
486// API
487
488// EXPECT
489
490/// Expect the absolute error between two values is less than epsilon.
491///
492/// Returns an error if `| a - b | > epsilon`.
493///
494/// * `a`       - First float.
495/// * `b`       - Second float.
496/// * `epsilon` - Absolute error tolerance between floats (defaults to
497///   `1.0e-6`).
498///
499/// # Examples
500///
501/// ```
502/// # use assert_float_eq::expect_float_absolute_eq;
503/// # pub fn main() {
504/// assert!(expect_float_absolute_eq!(3.0, 4.0, 1.0).is_ok());
505/// assert!(expect_float_absolute_eq!(3.0, 4.0, 0.9).is_err());
506/// assert!(expect_float_absolute_eq!(1.0, 0.5 + 0.5).is_ok());
507/// # }
508/// ```
509#[macro_export]
510macro_rules! expect_float_absolute_eq {
511    // Explicit epsilon, fail.
512    ($a:expr, $b:expr, $epsilon:expr) => {{
513        let (a, b, eps) = ($a, $b, $epsilon);
514        let r = $crate::afe_is_absolute_eq!(a, b, eps);
515        let e = $crate::AbsoluteEqError::new(a, b, eps);
516        $crate::bool_to_result(r, e)
517    }};
518    // No explicit epsilon, use default.
519    ($a:expr, $b:expr) => {
520        $crate::expect_float_absolute_eq!($a, $b, 1.0e-6)
521    };
522}
523
524/// Expect the absolute error between two values is greater than epsilon.
525///
526/// Returns an error if `| a - b | <= epsilon`.
527///
528/// * `a`       - First float.
529/// * `b`       - Second float.
530/// * `epsilon` - Absolute error tolerance between floats (defaults to
531///   `1.0e-6`).
532///
533/// # Examples
534///
535/// ```
536/// # use assert_float_eq::expect_float_absolute_ne;
537/// # pub fn main() {
538/// assert!(expect_float_absolute_ne!(3.0, 4.0, 1.0 + 1.0e-7).is_err());
539/// assert!(expect_float_absolute_ne!(3.0, 4.0, 1.0 - 1.0e-7).is_ok());
540/// # }
541/// ```
542#[macro_export]
543macro_rules! expect_float_absolute_ne {
544    // Explicit epsilon, fail.
545    ($a:expr, $b:expr, $epsilon:expr) => {{
546        let (a, b, eps) = ($a, $b, $epsilon);
547        let r = $crate::afe_is_absolute_eq!(a, b, eps);
548        let e = $crate::AbsoluteNeError::new(a, b, eps);
549        $crate::bool_to_result(!r, e)
550    }};
551    // No explicit epsilon, use default.
552    ($a:expr, $b:expr) => {
553        $crate::expect_float_absolute_ne!($a, $b, 1.0e-6)
554    };
555}
556
557/// Expect the relative error between two values is less than epsilon.
558///
559/// Returns an error if `|(a - b) / a| > epsilon`. If `a.is_infinite()`,
560/// then the result will always be ok. If `a.is_nan()`, then the result
561/// will always be an error.
562///
563/// * `a`       - First float.
564/// * `b`       - Second float.
565/// * `epsilon` - Relative error tolerance between floats (defaults to
566///   `1.0e-6`).
567///
568/// # Examples
569///
570/// ```
571/// # use assert_float_eq::expect_float_relative_eq;
572/// # pub fn main() {
573/// assert!(expect_float_relative_eq!(4.0, 3.0, 0.25).is_ok());
574/// assert!(expect_float_relative_eq!(4.0, 3.0, 0.20).is_err());
575/// assert!(expect_float_relative_eq!(1.0, 0.5 + 0.5).is_ok());
576/// # }
577/// ```
578#[macro_export]
579macro_rules! expect_float_relative_eq {
580    // Explicit epsilon, fail.
581    ($a:expr, $b:expr, $epsilon:expr) => {{
582        let (a, b, eps) = ($a, $b, $epsilon);
583        let r = $crate::afe_is_relative_eq!(a, b, eps);
584        let e = $crate::RelativeEqError::new(a, b, eps);
585        $crate::bool_to_result(r, e)
586    }};
587    // No explicit epsilon, use default.
588    ($a:expr, $b:expr) => {
589        $crate::expect_float_relative_eq!($a, $b, 1.0e-6)
590    };
591}
592
593/// Expect the relative error between two values is greater than epsilon.
594///
595/// Returns an error if `|(a - b) / a| <= epsilon`. If `a.is_infinite()`,
596/// then the result will always be an error. If `a.is_nan()`, then the
597/// result will always be ok.
598///
599/// * `a`       - First float.
600/// * `b`       - Second float.
601/// * `epsilon` - Relative error tolerance between floats (defaults to
602///   `1.0e-6`).
603///
604/// # Examples
605///
606/// ```
607/// # use assert_float_eq::expect_float_relative_ne;
608/// # pub fn main() {
609/// assert!(expect_float_relative_ne!(4.0, 3.0, 0.25).is_err());
610/// assert!(expect_float_relative_ne!(4.0, 3.0, 0.20).is_ok());
611/// assert!(expect_float_relative_ne!(1.0, 0.5 + 0.5).is_err());
612/// # }
613/// ```
614#[macro_export]
615macro_rules! expect_float_relative_ne {
616    // Explicit epsilon, fail.
617    ($a:expr, $b:expr, $epsilon:expr) => {{
618        let (a, b, eps) = ($a, $b, $epsilon);
619        let r = $crate::afe_is_relative_eq!(a, b, eps);
620        let e = $crate::RelativeNeError::new(a, b, eps);
621        $crate::bool_to_result(!r, e)
622    }};
623    // No explicit epsilon, use default.
624    ($a:expr, $b:expr) => {
625        $crate::expect_float_relative_ne!($a, $b, 1.0e-6)
626    };
627}
628
629/// Expect two 32-bit floats are within `n` steps of each other.
630///
631/// Returns an error if the two floats are more than `n` steps away
632/// from each other.
633///
634/// * `a`       - First float.
635/// * `b`       - Second float.
636/// * `n`       - Step tolerance between floats (defaults to `4`).
637///
638/// Each step is derived from the previous float by incrementing
639/// the float's bits, as if they were an integer, by 1.
640/// For example, the next float from 1e-45 (`0x00000001`) would be
641/// 3e-45 (`0x00000002`).
642///
643/// # Examples
644///
645/// ```rust
646/// # use assert_float_eq::expect_f32_near;
647/// # pub fn main() {
648/// assert!(expect_f32_near!(1e-45, 7e-45).is_ok());
649/// assert!(expect_f32_near!(1e-45, 1.4e-44, 9).is_ok());
650/// assert!(expect_f32_near!(1e-45, 1.4e-44, 8).is_err());
651/// assert!(expect_f32_near!(3e37, 3.000001e+37).is_ok());
652/// # }
653/// ```
654#[macro_export]
655macro_rules! expect_f32_near {
656    // Explicit steps.
657    ($a:expr, $b:expr, $n:expr) => {{
658        let (a, b, n) = ($a, $b, $n);
659        let (r, previous, next) = $crate::afe_is_f32_near!(a, b, n);
660        let e = $crate::FloatNearError::new(a, b, n, previous, next);
661        $crate::bool_to_result(r, e)
662    }};
663    // No explicit steps, use default.
664    ($a:expr, $b:expr) => {
665        $crate::expect_f32_near!($a, $b, 4)
666    };
667}
668
669/// Expect two 32-bit floats are not within `n` steps of each other.
670///
671/// Returns an error if the two floats are less than or equal to `n`
672/// steps away from each other.
673///
674/// * `a`       - First float.
675/// * `b`       - Second float.
676/// * `n`       - Step tolerance between floats (defaults to `4`).
677///
678/// Each step is derived from the previous float by incrementing
679/// the float's bits, as if they were an integer, by 1.
680/// For example, the next float from 1e-45 (`0x00000001`) would be
681/// 3e-45 (`0x00000002`).
682///
683/// # Examples
684///
685/// ```rust
686/// # use assert_float_eq::expect_f32_far;
687/// # pub fn main() {
688/// assert!(expect_f32_far!(1e-45, 7e-45).is_err());
689/// assert!(expect_f32_far!(1e-45, 1.4e-44, 9).is_err());
690/// assert!(expect_f32_far!(1e-45, 1.4e-44, 8).is_ok());
691/// assert!(expect_f32_far!(3e37, 3.000001e+37).is_err());
692/// # }
693/// ```
694#[macro_export]
695macro_rules! expect_f32_far {
696    // Explicit steps.
697    ($a:expr, $b:expr, $n:expr) => {{
698        let (a, b, n) = ($a, $b, $n);
699        let (r, previous, next) = $crate::afe_is_f32_near!(a, b, n);
700        let e = $crate::FloatFarError::new(a, b, n, previous, next);
701        $crate::bool_to_result(!r, e)
702    }};
703    // No explicit steps, use default.
704    ($a:expr, $b:expr) => {
705        $crate::expect_f32_far!($a, $b, 4)
706    };
707}
708
709/// Expect two 64-bit floats are within `n` steps of each other.
710///
711/// Returns an error if the two floats are more than `n` steps away
712/// from each other.
713///
714/// * `a`       - First float.
715/// * `b`       - Second float.
716/// * `n`       - Step tolerance between floats (defaults to `4`).
717///
718/// Each step is derived from the previous float by incrementing
719/// the float's bits, as if they were an integer, by 1.
720/// For example, the next float from 1e-45 (`0x00000001`) would be
721/// 3e-45 (`0x00000002`).
722///
723/// # Examples
724///
725/// ```rust
726/// # use assert_float_eq::expect_f64_near;
727/// # pub fn main() {
728/// assert!(expect_f64_near!(5e-324, 2.5e-323).is_ok());
729/// assert!(expect_f64_near!(5e-324, 2.5e-323, 3).is_err());
730/// assert!(expect_f64_near!(5e-324, 5e-323, 9).is_ok());
731/// assert!(expect_f64_near!(5e-324, 5e-323, 8).is_err());
732/// assert!(expect_f64_near!(3e300, 3.0000000000000025e+300).is_ok());
733/// # }
734/// ```
735#[macro_export]
736macro_rules! expect_f64_near {
737    // Explicit steps.
738    ($a:expr, $b:expr, $n:expr) => {{
739        let (a, b, n) = ($a, $b, $n);
740        let (r, previous, next) = $crate::afe_is_f64_near!(a, b, n);
741        let e = $crate::FloatNearError::new(a, b, n, previous, next);
742        $crate::bool_to_result(r, e)
743    }};
744    // No explicit steps, use default.
745    ($a:expr, $b:expr) => {
746        $crate::expect_f64_near!($a, $b, 4)
747    };
748}
749
750/// Expect two 64-bit floats are not within `n` steps of each other.
751///
752/// Returns an error if the two floats are less than or equal to `n`
753/// steps away from each other.
754///
755/// * `a`       - First float.
756/// * `b`       - Second float.
757/// * `n`       - Step tolerance between floats (defaults to `4`).
758///
759/// Each step is derived from the previous float by incrementing
760/// the float's bits, as if they were an integer, by 1.
761/// For example, the next float from 1e-45 (`0x00000001`) would be
762/// 3e-45 (`0x00000002`).
763///
764/// # Examples
765///
766/// ```rust
767/// # use assert_float_eq::expect_f64_far;
768/// # pub fn main() {
769/// assert!(expect_f64_far!(5e-324, 2.5e-323).is_err());
770/// assert!(expect_f64_far!(5e-324, 2.5e-323, 3).is_ok());
771/// assert!(expect_f64_far!(5e-324, 5e-323, 9).is_err());
772/// assert!(expect_f64_far!(5e-324, 5e-323, 8).is_ok());
773/// assert!(expect_f64_far!(3e300, 3.0000000000000025e+300).is_err());
774/// # }
775/// ```
776#[macro_export]
777macro_rules! expect_f64_far {
778    // Explicit steps.
779    ($a:expr, $b:expr, $n:expr) => {{
780        let (a, b, n) = ($a, $b, $n);
781        let (r, previous, next) = $crate::afe_is_f64_near!(a, b, n);
782        let e = $crate::FloatFarError::new(a, b, n, previous, next);
783        $crate::bool_to_result(!r, e)
784    }};
785    // No explicit steps, use default.
786    ($a:expr, $b:expr) => {
787        $crate::expect_f64_far!($a, $b, 4)
788    };
789}
790
791// ASSERT
792
793/// Assert the absolute error between two values is less than epsilon.
794///
795/// Panics if `| a - b | > epsilon`.
796///
797/// * `a`       - First float.
798/// * `b`       - Second float.
799/// * `epsilon` - Absolute error tolerance between floats (defaults to
800///   `1.0e-6`).
801///
802/// # Examples
803///
804/// ```
805/// # use assert_float_eq::assert_float_absolute_eq;
806/// # pub fn main() {
807/// assert_float_absolute_eq!(3.0, 4.0, 1.0);
808/// assert_float_absolute_eq!(3.0, 4.0, 1.0 + 1.0e-7);
809/// assert_float_absolute_eq!(1.0, 0.5 + 0.5);
810/// assert_float_absolute_eq!(1.0, 0.5 + 0.5 + 1.0e-7);
811/// assert_float_absolute_eq!(1.0, 0.5 + 0.5 - 1.0e-7);
812/// # }
813/// ```
814#[macro_export]
815macro_rules! assert_float_absolute_eq {
816    // Explicit epsilon, fail.
817    ($a:expr, $b:expr, $epsilon:expr) => {{
818        let (a, b, eps) = ($a, $b, $epsilon);
819        let r = $crate::afe_is_absolute_eq!(a, b, eps);
820        assert!(r, $crate::afe_absolute_eq_error_msg!(), a, b, eps)
821    }};
822    // No explicit epsilon, use default.
823    ($a:expr, $b:expr) => {
824        $crate::assert_float_absolute_eq!($a, $b, 1.0e-6)
825    };
826}
827
828/// Assert the absolute error between two values is greater than epsilon.
829///
830/// Panics if `| a - b | <= epsilon`.
831///
832/// * `a`       - First float.
833/// * `b`       - Second float.
834/// * `epsilon` - Absolute error tolerance between floats (defaults to
835///   `1.0e-6`).
836///
837/// # Examples
838///
839/// ```
840/// # use assert_float_eq::assert_float_absolute_ne;
841/// # pub fn main() {
842/// assert_float_absolute_ne!(3.0, 4.0, 0.99);
843/// assert_float_absolute_ne!(1.0, 0.5 + 0.499);
844/// # }
845/// ```
846#[macro_export]
847macro_rules! assert_float_absolute_ne {
848    // Explicit epsilon, fail.
849    ($a:expr, $b:expr, $epsilon:expr) => {{
850        let (a, b, eps) = ($a, $b, $epsilon);
851        let r = $crate::afe_is_absolute_eq!(a, b, eps);
852        assert!(!r, $crate::afe_absolute_ne_error_msg!(), a, b, eps)
853    }};
854    // No explicit epsilon, use default.
855    ($a:expr, $b:expr) => {
856        $crate::assert_float_absolute_ne!($a, $b, 1.0e-6)
857    };
858}
859
860/// Assert the relative error between two values is less than epsilon.
861///
862/// Panics if `|(a - b) / a| > epsilon`. If `a.is_infinite()`, then this
863/// will never panic. If `a.is_nan()`, then this will always panic.
864///
865/// * `a`       - First float.
866/// * `b`       - Second float.
867/// * `epsilon` - Relative error tolerance between floats (defaults to
868///   `1.0e-6`).
869///
870/// # Examples
871///
872/// ```
873/// # use assert_float_eq::assert_float_relative_eq;
874/// # pub fn main() {
875/// assert_float_relative_eq!(4.0, 3.0, 0.25);
876/// assert_float_relative_eq!(1.0, 0.5 + 0.5);
877/// # }
878/// ```
879#[macro_export]
880macro_rules! assert_float_relative_eq {
881    // Explicit epsilon, fail.
882    ($a:expr, $b:expr, $epsilon:expr) => {{
883        let (a, b, eps) = ($a, $b, $epsilon);
884        let r = $crate::afe_is_relative_eq!(a, b, eps);
885        assert!(r, $crate::afe_relative_eq_error_msg!(), a, b, eps)
886    }};
887    // No explicit epsilon, use default.
888    ($a:expr, $b:expr) => {
889        $crate::assert_float_relative_eq!($a, $b, 1.0e-6)
890    };
891}
892
893/// Assert the relative error between two values is greater than epsilon.
894///
895/// Panics if `|(a - b) / a| <= epsilon`. If `a.is_infinite()`, then this
896/// will always panic. If `a.is_nan()`, then this will never panic.
897///
898/// * `a`       - First float.
899/// * `b`       - Second float.
900/// * `epsilon` - Relative error tolerance between floats (defaults to
901///   `1.0e-6`).
902///
903/// # Examples
904///
905/// ```
906/// # use assert_float_eq::assert_float_relative_ne;
907/// # pub fn main() {
908/// assert_float_relative_ne!(4.0, 3.0, 0.25 - 1.0e-7);
909/// assert_float_relative_ne!(1.0, 0.5 + 0.5 + 1e-5);
910/// # }
911/// ```
912#[macro_export]
913macro_rules! assert_float_relative_ne {
914    // Explicit epsilon, fail.
915    ($a:expr, $b:expr, $epsilon:expr) => {{
916        let (a, b, eps) = ($a, $b, $epsilon);
917        let r = $crate::afe_is_relative_eq!(a, b, eps);
918        assert!(!r, $crate::afe_relative_ne_error_msg!(), a, b, eps)
919    }};
920    // No explicit epsilon, use default.
921    ($a:expr, $b:expr) => {
922        $crate::assert_float_relative_ne!($a, $b, 1.0e-6)
923    };
924}
925
926/// Assert two 32-bit floats are within `n` steps of each other.
927///
928/// Panics if the two floats are more than `n` steps away from each other.
929///
930/// * `a`       - First float.
931/// * `b`       - Second float.
932/// * `n`       - Step tolerance between floats (defaults to `4`).
933///
934/// Each step is derived from the previous float by incrementing
935/// the float's bits, as if they were an integer, by 1.
936/// For example, the next float from 1e-45 (`0x00000001`) would be
937/// 3e-45 (`0x00000002`).
938///
939/// # Examples
940///
941/// ```rust
942/// # use assert_float_eq::assert_f32_near;
943/// # pub fn main() {
944/// assert_f32_near!(1e-45, 7e-45);
945/// assert_f32_near!(1e-45, 1.4e-44, 9);
946/// assert_f32_near!(3e37, 3.000001e+37);
947/// # }
948/// ```
949#[macro_export]
950macro_rules! assert_f32_near {
951    // Explicit steps.
952    ($a:expr, $b:expr, $n:expr) => {{
953        let (a, b, n) = ($a, $b, $n);
954        let (r, previous, next) = $crate::afe_is_f32_near!(a, b, n);
955        assert!(r, $crate::afe_near_error_msg!(), a, b, n, previous, next)
956    }};
957    // No explicit steps, use default.
958    ($a:expr, $b:expr) => {
959        $crate::assert_f32_near!($a, $b, 4)
960    };
961}
962
963/// Assert two 32-bit floats are not within `n` steps of each other.
964///
965/// Panics if the two floats are less than or equal to `n` steps away
966/// from each other.
967///
968/// * `a`       - First float.
969/// * `b`       - Second float.
970/// * `n`       - Step tolerance between floats (defaults to `4`).
971///
972/// Each step is derived from the previous float by incrementing
973/// the float's bits, as if they were an integer, by 1.
974/// For example, the next float from 1e-45 (`0x00000001`) would be
975/// 3e-45 (`0x00000002`).
976///
977/// # Examples
978///
979/// ```rust
980/// # use assert_float_eq::assert_f32_far;
981/// # pub fn main() {
982/// assert_f32_far!(1e-45, 8e-45);
983/// assert_f32_far!(1e-45, 1.4e-44, 8);
984/// assert_f32_far!(3e37, 3.0000014e+37);
985/// # }
986/// ```
987#[macro_export]
988macro_rules! assert_f32_far {
989    // Explicit steps.
990    ($a:expr, $b:expr, $n:expr) => {{
991        let (a, b, n) = ($a, $b, $n);
992        let (r, previous, next) = $crate::afe_is_f32_near!(a, b, n);
993        assert!(!r, $crate::afe_far_error_msg!(), a, b, n, previous, next)
994    }};
995    // No explicit steps, use default.
996    ($a:expr, $b:expr) => {
997        $crate::assert_f32_far!($a, $b, 4)
998    };
999}
1000
1001/// Assert two 64-bit floats are within `n` steps of each other.
1002///
1003/// Panics if the two floats are more than `n` steps away from each other.
1004///
1005/// * `a`       - First float.
1006/// * `b`       - Second float.
1007/// * `n`       - Step tolerance between floats (defaults to `4`).
1008///
1009/// Each step is derived from the previous float by incrementing
1010/// the float's bits, as if they were an integer, by 1.
1011/// For example, the next float from 5.e-324 (`0x0000000000000001`) would be
1012/// 1.e-323 (`0x0000000000000002`).
1013///
1014/// # Examples
1015///
1016/// ```rust
1017/// # use assert_float_eq::assert_f64_near;
1018/// # pub fn main() {
1019/// assert_f64_near!(5e-324, 2.5e-323);
1020/// assert_f64_near!(5e-324, 5e-323, 9);
1021/// assert_f64_near!(3e300, 3.0000000000000025e+300);
1022/// # }
1023/// ```
1024#[macro_export]
1025macro_rules! assert_f64_near {
1026    // Explicit steps.
1027    ($a:expr, $b:expr, $n:expr) => {{
1028        let (a, b, n) = ($a, $b, $n);
1029        let (r, previous, next) = $crate::afe_is_f64_near!(a, b, n);
1030        assert!(r, $crate::afe_near_error_msg!(), a, b, n, previous, next)
1031    }};
1032    // No explicit steps, use default.
1033    ($a:expr, $b:expr) => {
1034        $crate::assert_f64_near!($a, $b, 4)
1035    };
1036}
1037
1038/// Assert two 64-bit floats are not within `n` steps of each other.
1039///
1040/// Panics if the two floats are less than or equal to `n` steps away
1041/// from each other.
1042///
1043/// * `a`       - First float.
1044/// * `b`       - Second float.
1045/// * `n`       - Step tolerance between floats (defaults to `4`).
1046///
1047/// Each step is derived from the previous float by incrementing
1048/// the float's bits, as if they were an integer, by 1.
1049/// For example, the next float from 5.e-324 (`0x0000000000000001`) would be
1050/// 1.e-323 (`0x0000000000000002`).
1051///
1052/// # Examples
1053///
1054/// ```rust
1055/// # use assert_float_eq::assert_f64_far;
1056/// # pub fn main() {
1057/// assert_f64_far!(5e-324, 3e-323);
1058/// assert_f64_far!(5e-324, 5.4e-323, 9);
1059/// assert_f64_far!(3e300, 3.000000000000007e+300);
1060/// # }
1061/// ```
1062#[macro_export]
1063macro_rules! assert_f64_far {
1064    // Explicit steps.
1065    ($a:expr, $b:expr, $n:expr) => {{
1066        let (a, b, n) = ($a, $b, $n);
1067        let (r, previous, next) = $crate::afe_is_f64_near!(a, b, n);
1068        assert!(!r, $crate::afe_far_error_msg!(), a, b, n, previous, next)
1069    }};
1070    // No explicit steps, use default.
1071    ($a:expr, $b:expr) => {
1072        $crate::assert_f64_far!($a, $b, 4)
1073    };
1074}
1075
1076// TESTS
1077// -----
1078
1079#[cfg(test)]
1080mod tests {
1081    use core::f32;
1082
1083    use super::*;
1084
1085    #[test]
1086    #[should_panic]
1087    fn absolute_eq_fail() {
1088        assert_float_absolute_eq!(3.0, 4.0, 0.9);
1089    }
1090
1091    #[test]
1092    fn absolute_eq_succeed() {
1093        assert_float_absolute_eq!(3.0, 4.0, 1.0);
1094    }
1095
1096    #[test]
1097    #[should_panic]
1098    fn relative_eq_fail() {
1099        assert_float_relative_eq!(4.0, 3.0, 0.2);
1100    }
1101
1102    #[test]
1103    fn relative_eq_succeed() {
1104        assert_float_relative_eq!(4.0, 3.0, 0.26);
1105    }
1106
1107    #[test]
1108    #[should_panic]
1109    fn relative_eq_negative_zero_fail() {
1110        assert_float_relative_eq!(-0.1, 0.0);
1111    }
1112
1113    #[test]
1114    #[should_panic]
1115    fn f32_near_fail() {
1116        assert_f32_near!(1.0e-45, 7.0e-45, 3);
1117    }
1118
1119    #[test]
1120    fn f32_near_succeed() {
1121        assert_f32_near!(1.0e-45, 7.0e-45, 4);
1122    }
1123
1124    #[test]
1125    #[should_panic]
1126    fn f64_near_fail() {
1127        assert_f64_near!(5.0e-324, 2.5e-323, 3);
1128    }
1129
1130    #[test]
1131    #[should_panic]
1132    fn f64_far_fail() {
1133        assert_f64_far!(5.0e-324, 2.5e-323, 4);
1134    }
1135
1136    #[test]
1137    fn f64_near_succeed() {
1138        assert_f64_near!(5.0e-324, 2.5e-323, 4);
1139    }
1140
1141    #[test]
1142    fn f64_far_succeed() {
1143        assert_f64_far!(5.0e-324, 3e-323, 4);
1144    }
1145
1146    #[test]
1147    fn issue_03() {
1148        assert!(expect_float_relative_eq!(f32::INFINITY, f32::MAX, f32::INFINITY).is_ok());
1149        assert!(expect_float_relative_eq!(f32::INFINITY, f32::MAX, 0.0).is_ok());
1150        assert!(expect_float_relative_eq!(f32::MAX, f32::INFINITY, f32::INFINITY).is_ok());
1151
1152        let error = expect_float_relative_eq!(f32::MAX, f32::INFINITY, 1.0).unwrap_err();
1153        assert_eq!(error.a, f32::MAX);
1154        assert_eq!(error.b, f32::INFINITY);
1155        assert_eq!(error.epsilon, 1.0);
1156    }
1157}