Skip to main content

assert_eq_float/
lib.rs

1/*!
2# assert-eq-float
3
4This crate provides the `assert_eq_float!` macros that support floats.
5
6## Examples
7
8```rust
9use assert_eq_float::*;
10
11assert_eq_float!(1.1 + 0.1, 1.2);       // error = 0.0000000000000021316282072803005
12assert_eq_float!(1e100 + 2e100, 3e100); // error = 53290705182007510000000000000000000000000000000000000000000000000000000000000000000000
13
14// other macros
15debug_assert_eq_float!(0.0, 0.0);
16assert_ne_float!(0.0, 0.1);
17debug_assert_ne_float!(0.0, 0.1);
18```
19
20The default margin of error is dynamically computed by properties of IEEE 754 floating point numbers. You don't need to worry about it if you just want to check two float values are **equal**.
21*/
22
23#![no_std]
24
25mod eq;
26mod ne;
27
28#[doc(hidden)]
29pub trait FloatExt: Copy {
30    fn abs(self) -> Self;
31    fn __get_error(self, other: Self) -> Self;
32}
33
34impl FloatExt for f32 {
35    #[inline]
36    fn abs(self) -> Self {
37        f32::abs(self)
38    }
39
40    #[inline]
41    fn __get_error(self, other: Self) -> Self {
42        // See: https://magiclen.org/float-precision/
43        self.abs().min(other.abs()) * f32::EPSILON * 8.0
44    }
45}
46
47impl FloatExt for f64 {
48    #[inline]
49    fn abs(self) -> Self {
50        f64::abs(self)
51    }
52
53    #[inline]
54    fn __get_error(self, other: Self) -> Self {
55        // See: https://magiclen.org/float-precision/
56        self.abs().min(other.abs()) * f64::EPSILON * 8.0
57    }
58}
59
60#[doc(hidden)]
61#[inline]
62pub fn get_error<T: FloatExt>(a: T, b: T) -> T {
63    a.__get_error(b)
64}