## no-std float_eq

Compare IEEE floating point primitives, structs and collections for equality

### 15 releases(2 stable)

 1.0.1 Oct 12, 2022 Jun 2, 2022 Oct 3, 2021 Jul 31, 2021 Jun 22, 2020

#17 in Algorithms

Used in 63 crates (45 directly)

MIT/Apache

195KB
4K SLoC

# float_eq

Compare IEEE floating point primitives, structs and collections for equality.

This crate provides an API with a focus on making the choices of comparison algorithm(s) and tolerances intuitive to implementers and maintainers, and of providing clear output for debugging and development iteration.

This readme is a quick tour of the crate. For introductory material, guides and discussion see the float_eq guide.

## Usage

``````[dependencies]
float_eq = "1"
``````

And, if you're using the 2015 edition, this to your crate root:

``````extern crate float_eq;
``````

Then, you can import items with `use`:

``````use float_eq::{assert_float_eq, float_eq};
``````

## Comparisons

This crate provides boolean comparison operations:

``````if (float_eq!(y_pos, 0.0, abs <= 0.000_1)) {
//...
}
``````

And asserts:

``````const RECIP_REL_TOL: f32 = 0.000_366_210_94;
assert_float_eq!(x.recip(), 10.0, r2nd <= RECIP_REL_TOL);
``````

Using absolute tolerance, relative tolerance or ULPs based comparison algorithms.

## Composite types

Composite types may implement the provided extension traits to be compared on a field-by-field basis:

``````let a = Complex32 { re: 2.0, im: 4.000_002 };
let b = Complex32 { re: 2.000_000_5, im: 4.0 };

assert_float_eq!(a, b, ulps <= ComplexUlps32 { re: 2, im: 4 });
``````

...and if they are homogeneous, with a uniformly applied tolerance across all fields:

``````assert_float_eq!(a, b, ulps_all <= 4);
``````

Arrays of any size are supported:

``````let a = [1.0, -2.0, 3.0];
let b = [-1.0, 2.0, 3.5];
assert_float_eq!(a, b, abs <= [2.0, 4.0, 0.5]);
assert_float_eq!(a, b, abs_all <= 4.0);
``````

As are tuples up to size 12 (inclusive):

``````let a = (1.0f32, 2.0f64);
let b = (1.5f32, -2.0f64);
assert_float_eq!(a, b, r2nd <= (0.5, 2.0));
``````

Many standard and core types like `Vec` are supported:

``````let a = vec![1.0, -2.0, 3.0];
let b = vec![-1.0, 2.0, 3.5];
assert_float_eq!(a, b, rmax <= vec![2.0, 2.0, 0.25]);
assert_float_eq!(a, b, rmax_all <= 2.0);
``````

There are blanket trait impls for comparing mutable and immutable reference types, the contents of `Cell`, `RefCell`, `Rc`, `Arc` and `Box` instances, as well as for slices, `Option`, `Vec`, `VecDeque`, `LinkedList`, `BTreeMap` and `HashMap`.

## Derivable

The extension traits may be derived for non-generic structs and tuple structs:

``````#[derive_float_eq(
ulps_tol = "PointUlps",
ulps_tol_derive = "Clone, Copy, Debug, PartialEq",
debug_ulps_diff = "PointUlpsDebugUlpsDiff",
debug_ulps_diff_derive = "Clone, Copy, Debug, PartialEq",
all_tol = "f64"
)]
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Point {
pub x: f64,
pub y: f64,
}

let a = Point { x: 1.0, y: -2.0 };
let c = Point {
x: 1.000_000_000_000_000_9,
y: -2.000_000_000_000_001_3
};
assert_float_eq!(a, c, ulps <= PointUlps { x: 4, y: 3 });
assert_float_eq!(a, c, ulps_all <= 4);
``````

## Error messages

Asserts provide additional useful context information. For example:

``````assert_float_eq!(4.0f32, 4.000_008, rmax <= 0.000_001);
``````

Panics with this error message:

``````thread 'main' panicked at 'assertion failed: `float_eq!(left, right, rmax <= t)`
left: `4.0`,
right: `4.000008`,
abs_diff: `0.000008106232`,
ulps_diff: `Some(17)`,
[rmax] t: `0.000004000008`', assert_failure.rs:15:5
``````

Where `[rmax] t` shows the tolerance value that the absolute difference was compared against after being appropriately scaled.

## Optional features

This crate can be used without the standard library (`#![no_std]`) by disabling the default `std` feature. Use this in `Cargo.toml`:

``````[dependencies.float_eq]
version = "1"
default-features = false
``````

Other optional features:

• derive — provides custom derive macros for all traits.
• num — blanket trait impls for `num::Complex` where it is instanced with a compatible type.

The `approx`, `float-cmp`, `assert_float_eq` and `is_close` crates provide similar floating point comparison capabilities to `float_eq`. The `almost` crate divides its API into comparison of floats against zero and non-zero values. The `efloat` crate provides an `f32` equivalent type that tracks the maximum possible error bounds that may have occured due to rounding.

The `ieee754` crate is not a comparison library, but provides useful functionality for decomposing floats into their component parts, iterating over representable values and working with ULPs directly, amoung other things.

## Contributing

Constructive feedback, suggestions and contributions welcomed, please open an issue.

## Changelog

Release information is available in CHANGELOG.md.

~0–255KB