Announcing `float_eq` 0.4.0


I've just published version 0.4.0 of float_eq, for comparing floating point values.

This release adds support for comparing the contents of more standard Rust types - slices, Option, Vec, VecDeque, LinkedList, BTreeMap and HashMap:

let a = vec![1.0f32, 2.0];
let b = vec![1.000_000_1, 2.000_000_5];

assert_float_eq!(a, b, ulps <= vec![1, 2]);
assert_float_eq!(a, b, ulps_all <= 2);

This is in addition to the support added in 0.3.1 for comparing mutable and immutable reference types and the contents of Cell, RefCell, Rc, Arc and Box instances.

You may also now #[derive] any or all of the float_eq traits for non-generic structs and tuple structs, by enabling the optional "derive" feature:

    Debug, PartialEq, FloatUlps, FloatDiff, FloatEq, FloatEqDebug,
    FloatEqAll, FloatEqAllDebug,
#[float_eq(ulps = "PointUlps", all_epsilon = "f64")]
struct Point {
    x: f64,
    y: f64,

let a = Point { x: 1.0, y: -2.0 };
let b = Point { x: 1.1, y: -2.2 };
assert_float_eq!(a, b, abs <= Point { x: 0.15, y: 0.25 });
assert_float_eq!(a, b, abs_all <= 0.25);

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);

How does float_eq differ from approx?

Both provide similar comparison capabilities, with different underlying philosophies and APIs, see this post for a longer discussion.

Why write yet another floating point equality library?

To explore providing a different kind of toolkit for working with floating point numbers. Since I am fairly new to Rust (though very experienced with C++) it seemed like a good way to introduce myself to some of the more advanced language and ecosystem features. Finally, I wanted to gain a deeper intuition for floating point representation and usage and you know what they say - don't reinvent the wheel unless you're planning on learning how wheels work :slight_smile:

1 Like