[][src]Crate is_close

Determine whether floating point numbers are close in value

In use cases such as testing it is often times more useful to know whether two floating point numbers are close to each other rather than exactly equal. Due to finite precision of computers, we usually cannot even expect bitwise equality of two values even if underlaying math suggests it. This is where is_close comes in. The crate is strongly inspired by Python's PEP 485 aka math.isclose.

Examples

Basic usage ...

extern crate is_close;
use is_close::default as ic;

assert!(ic().is_close(42.0, 42.0));
assert!(!ic().is_close(13.0, 37.0));

assert!(ic().all_close(vec![9.0, 10.0], vec![9.0, 10.0]));
assert!(!ic().all_close(vec![0.0, 10.0], vec![9.0, 10.0]));

assert!(ic().any_close(vec![0.0, 10.0], vec![9.0, 10.0]));
assert!(!ic().any_close(vec![0.0, 0.0], vec![9.0, 10.0]));

... the same with macros

#[macro_use]
extern crate is_close;

assert!(is_close!(42.0, 42.0));
assert!(!is_close!(13.0, 37.0));

assert!(all_close!(vec![9.0, 10.0], vec![9.0, 10.0]));
assert!(!all_close!(vec![0.0, 10.0], vec![9.0, 10.0]));

assert!(any_close!(vec![0.0, 10.0], vec![9.0, 10.0]));
assert!(!any_close!(vec![0.0, 0.0], vec![9.0, 10.0]));

Configuration

There are different ways to determine whether two values are close to each other or not. is_close comes with sane default settings. However, the following examples illustrate how to tweak the comparison:

Relative Tolerance: the amount of error allowed, relative to the magnitude of the input values:

assert!(ic().rel_tol(1e-2).is_close(9.9, 10.0));
assert!(!ic().rel_tol(1e-3).is_close(9.9, 10.0));

Absolute Tolerance: useful for comparisons to zero:

assert!(ic().abs_tol(1e-1).is_close(0.0, 0.1));
assert!(!ic().abs_tol(1e-2).is_close(0.0, 0.1));

Other Methods: the strategy of how to interpret relative tolerance, see Method:

use is_close::{ASYMMETRIC, WEAK, STRONG, AVERAGE};

// Relative tolerance is scaled by the larger of the two values (default)
assert!(ic().method("weak").rel_tol(1e-1).is_close(9.0, 10.0));
assert!(ic().method("weak").rel_tol(1e-1).is_close(10.0, 9.0));
assert!(!ic().method(WEAK).rel_tol(1e-2).is_close(9.0, 10.0));
assert!(!ic().method(WEAK).rel_tol(1e-2).is_close(10.0, 9.0));

// Relative tolerance is scaled by the smaller of the two values
assert!(all_close!(vec![9.0, 10.0], vec![10.0, 9.0], rel_tol=2e-1, method="STRONG"));
assert!(!any_close!(vec![9.0, 10.0], vec![10.0, 9.0], rel_tol=1e-1, method=STRONG));

// Relative tolerance is scaled by the average of the two values
assert!(is_close!(9.0, 10.0, rel_tol=2e-1, method="average"));
assert!(is_close!(10.0, 9.0, rel_tol=2e-1, method="average"));
assert!(!is_close!(9.0, 10.0, rel_tol=1e-1, method=AVERAGE));
assert!(!is_close!(10.0, 9.0, rel_tol=1e-1, method=AVERAGE));

// The second value (`b`) is used for scaling the tolerance
assert!(ic().method("asymmetric").rel_tol(1e-1).is_close(9.0, 10.0));
assert!(!ic().method(ASYMMETRIC).rel_tol(1e-1).is_close(10.0, 9.0));

Macros

all_close

Check whether or not two iterables a and b are pairwise "close" to each other

any_close

Check whether or not two iterables a and b are pairwise "close" to each other in at least one place

is_close

Check whether or not two values a and b are "close" to each other

Structs

IsClose

Compare two floats with some tolerance

Enums

Method

Strategies of handling relative tolerance

Constants

ASYMMETRIC

Shorthand for Method::Asymmetric

AVERAGE

Shorthand for Method::Average

STRONG

Shorthand for Method::Strong

WEAK

Shorthand for Method::Weak

Functions

default

Create default IsClose configuration: { rel_tol: 1e-8, abs_tol: 0.0, method: "weak" }