Expand description
Test floating point numbers for equality
In scenarios like 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;
assert!(default().is_close(42.0, 42.0));
assert!(!default().is_close(13.0, 37.0));
assert!(default().all_close(vec![9.0, 10.0], vec![9.0, 10.0]));
assert!(!default().all_close(vec![0.0, 10.0], vec![9.0, 10.0]));
assert!(default().any_close(vec![0.0, 10.0], vec![9.0, 10.0]));
assert!(!default().any_close(vec![0.0, 0.0], vec![9.0, 10.0]));
… and 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]));
§Advanced Usage
There are different ways to determine whether two values are close to each other or not.
A few paramenters playing into the comparison of two floats. While is_close
comes with sane
[default settings], following examples illustrate how to tweak the comparison
to suit your needs:
§Relative Tolerance
The amount of error allowed, relative to the magnitude of the input values.
Check out Method
.
assert!(is_close!(9.9, 10.0, rel_tol=1e-2));
assert!(!is_close!(9.9, 10.0, rel_tol=1e-3));
§Absolute Tolerance
The absolute tolerance is useful for comparisons near zero.
assert!(is_close!(0.0, 0.1, abs_tol=1e-1));
assert!(!is_close!(0.0, 0.1, abs_tol=1e-2));
§Methods:
The strategy of how to interpret relative tolerance, see Method
:
Weak (default): relative tolerance is scaled by the larger of the two values
use is_close::WEAK;
assert!(default().method("weak").rel_tol(1e-1).is_close(9.0, 10.0));
assert!(!default().method(WEAK).rel_tol(1e-2).is_close(9.0, 10.0));
Strong: relative tolerance is scaled by the smaller of the two values
use is_close::STRONG;
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));
Average: relative tolerance is scaled by the average of the two values
use is_close::AVERAGE;
assert!(is_close!(9.0, 10.0, rel_tol=2e-1, method="average"));
assert!(!is_close!(9.0, 10.0, rel_tol=1e-1, method=AVERAGE));
Asymmetric: the second value (b
) is used for scaling the tolerance
use is_close::ASYMMETRIC;
let ic = default().method(ASYMMETRIC).rel_tol(1e-1).compile();
assert!(ic.is_close(9.0, 10.0));
assert!(!ic.is_close(10.0, 9.0));
Macros§
- all_
close - Check whether or not two iterables
a
andb
are pairwise close to each other - any_
close - Check whether or not two iterables
a
andb
are pairwise close to each other in at least one place - is_
close - Check whether or not two values
a
andb
are close to each other
Structs§
- Comparator
- Float Comparator
- Comparator
Builder - Builder for
Comparator
functions. It holds the following parameters:
Enums§
- Method
- Strategies for handling relative tolerance
Constants§
- ASYMMETRIC
- Shorthand for
Method::Asymmetric
- AVERAGE
- Shorthand for
Method::Average
- DEFAULT_
ABS_ TOL - Default absolute tolerance
- DEFAULT_
REL_ TOL - Default relative tolerance
- 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" }