Crate ballpark

Crate ballpark 

Source
Expand description

Approximate equality.

This crate provides mechanisms for comparing floating-point numbers and structures containing floating-point numbers for approximate equality in the presence of rounding and measurement errors.

§Comparisons

The approx_eq function can be used to compare two values for approximate equality.

approx_eq returns a Comparison, which has to be dereferenced to obtain the comparison result as a bool. It can also be inverted to get the inverted result.

use ballpark::approx_eq;

if !approx_eq(1.0, 1.0 + f64::EPSILON) {
    panic!("these are only a single `f64` apart, so they should be approximately equal");
}
if *approx_eq(10.0, 11.0) {
    panic!("10 and 11 are pretty far apart, so they should not be considered equal");
}

Comparison allows configuring the specific type of comparison and tolerance threshold with the Comparison::abs, Comparison::rel, and Comparison::ulps methods.

If none of these methods are used to customize the comparison, a default comparison is performed, which is a Comparison::ulps comparison with a tolerance of 4 ULPs.

§Assertions

One of the most common use cases of this crate is to assert that two values are almost equal, up to some tolerance value. This can be done via the assert_approx_eq! and assert_approx_ne! macros, which work similarly to assert_eq! and assert_ne!, respectively.

use ballpark::assert_approx_eq;

// Basic usage:
let a = 10.0;
let b = 1.0 / (1.0 / a);
assert_approx_eq!(a, b);

// Like `assert_eq!`, it supports a custom panic message:
assert_approx_eq!(a, b, "inverting {} twice should give the same result", a);

Unlike assert_eq! and assert_ne!, which evaluate to (), the assertion macros in ballpark return an Assertion object that can be used to set custom comparison thresholds:

use ballpark::{assert_approx_eq, assert_approx_ne};

// These values are too far away for the default comparison to consider them equal:
let a = 10.0;
let b = 10.1;

assert_approx_ne!(a, b);

// The values are less than 0.25 apart, so an *absolute difference* comparison with a tolerance
// of 0.25 will treat them as equal:
assert_approx_eq!(a, b).abs(0.25);

// They are also within 1% of each other, so a relative comparison with a tolerance of 0.01
// also treats them as equal:
assert_approx_eq!(a, b).rel(0.01);

§Custom Types

User-defined types can implement the ApproxEq trait to become compatible with this crate. All methods of ApproxEq should forward the operation to all contained fields that contribute to a type’s PartialEq result and && the results.

use ballpark::ApproxEq;

pub struct Vec2<T> {
    x: T,
    y: T,
}

impl<T: ApproxEq> ApproxEq for Vec2<T> {
    type Tolerance = T::Tolerance;

    fn abs_eq(&self, other: &Self, abs_tolerance: Self::Tolerance) -> bool {
        self.x.abs_eq(&other.x, abs_tolerance) &&
            self.y.abs_eq(&other.y, abs_tolerance)
    }

    fn rel_eq(&self, other: &Self, rel_tolerance: Self::Tolerance) -> bool {
        self.x.rel_eq(&other.x, rel_tolerance) &&
            self.y.rel_eq(&other.y, rel_tolerance)
    }

    fn ulps_eq(&self, other: &Self, ulps_tolerance: u32) -> bool {
        self.x.ulps_eq(&other.x, ulps_tolerance) &&
            self.y.ulps_eq(&other.y, ulps_tolerance)
    }
}

§Cargo Features

This library exposes the following Cargo features:

  • std (enabled by default): implements ApproxEq for some types in libstd.
  • alloc (enabled by default): implements ApproxEq for data structures and collections from the alloc crate.
  • f16: implements ApproxEq for Rust’s unstable f16 type. Requires a nightly compiler.
  • f128: implements ApproxEq for Rust’s unstable f128 type. Requires a nightly compiler.

Turning off the std feature makes this library #![no_std], and with alloc also turned off, it becomes usable in environments that don’t have a #[global_allocator].

Macros§

assert_approx_eq
Asserts that two expressions are approximately equal to each other (using ApproxEq).
assert_approx_ne
Asserts that two expressions are not approximately equal to each other (using ApproxEq).
debug_assert_approx_eq
Debug-asserts that two expressions are approximately equal to each other.
debug_assert_approx_ne
Debug-asserts that two expressions are not approximately equal to each other.

Structs§

Assertion
Assertion guard returned by assert_approx_eq! and assert_approx_ne!.
Comparison
Comparator for approximate equality of values.

Traits§

ApproxEq
Types that can be compared for approximate equality.

Functions§

approx_eq
Compares two values using approximate equality.