### 15 releases (2 stable)

1.0.1 | Oct 12, 2022 |
---|---|

1.0.0 | Jun 2, 2022 |

0.7.0 | Oct 3, 2021 |

0.6.1 | Jul 31, 2021 |

0.4.1 | Jun 22, 2020 |

#**17** in Algorithms

**54,986** downloads per month

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

Add this to your cargo.toml:

`[``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.``0``f32``,` `2.``0``f64``)``;`
`let` b `=` `(``1.``5``f32``,` `-``2.``0``f64``)``;`
`assert_float_eq!``(`a`,` b`,` r2nd `<=` `(``0.``5``,` `2.``0``)``)``;`

Many standard and core types like

are supported:`Vec`

`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`

and `Arc`

instances, as
well as for slices, `Box`

, `Option`

, `Vec`

, `VecDeque`

, `LinkedList`

and
`BTreeMap`

.`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.``0``f32``,` `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

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

## Optional features

This crate can be used without the standard library (

) by disabling
the default `#!``[``no_std``]`

feature. Use this in `std`

:`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

where it is instanced with a compatible type.`num`Complex`::`

## Related efforts

The

, `approx`

, `float-cmp`

and `assert_float_eq`

crates provide
similar floating point comparison capabilities to `is_close`

. The `float_eq`

crate
divides its API into comparison of floats against zero and non-zero values. The
`almost`

crate provides an `efloat`

equivalent type that tracks the maximum
possible error bounds that may have occured due to rounding.`f32`

The

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.`ieee754`

## Contributing

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

## Changelog

Release information is available in CHANGELOG.md.

#### Dependencies

~0–255KB