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}