Crate float_cmp [] [src]

Defines traits ApproxEq, ApproxOrd, and Ulps, for approximate comparison of floating point types. Defines implementations for f32 and f64

Floating point operations must round answers to the nearest representable number. Multiple operations, then, may result in an answer different than what you expect. In the following example, the assert will fail, even though the printed output says "0.45 == 0.45":

  let a = 0.15_f32 + 0.15_f32 + 0.15_f32;
  let b = 0.1_f32 + 0.1_f32 + 0.25_f32;
  println!("{} == {}", a, b);
  assert!(a==b)  // Fails, because they are not exactly equal

With an approximate comparison, we could get the answer we intend:

  let a = 0.15_f32 + 0.15_f32 + 0.15_f32;
  let b = 0.1_f32 + 0.1_f32 + 0.25_f32;
  println!("{} == {}", a, b);
  assert!(a.approx_eq(&b,2)) // They are equal, within 2 ulps

We use the term "ulp" (units in the last place, or units of least precision) to mean the unit of distance between two adjacent floating point representations (adjacent meaning that there is no floating point number between them). The size of an ulp (measured as a float) varies depending on the exponents of the floating point numbers in question, but this is quite useful, for it is the non-variation of a fixed epsilon (e.g. 0.0000001) which causes epsilon-based comparisons to so often fail with more extreme floating point values.

What we do is define approximate comparison by specifying the maximum number of ULPs that the comparands are allowed to differ by.

Traits

ApproxEq

ApproxEq is a trait for approximate equality comparisons, and is defined only for floating point types.

ApproxOrd

ApproxOrd is for sorting floating point values where approximate equality is considered equal.

Ulps