Equalish (equalish v1.0.0)

Copy Markdown

Equality operators for floats that are almost equal. Smooths out rounding errors and floating point precision issues.

import Equalish

# As a macro
assert is_eq_ish(0.5, 0.50000001)
#=> true

# As a guard
def foo(a, b) when is_eq_ish(a, b) do
  ...
end

Tolerance

The default tolerance is 1.0e-5, which is to say that two numbers are considered equal if their first 5 decimal places are the same.

You can change this in your config file with:

config :equalish,
  tolerance: 1.0e-5 # <- Change this

Examples below sometimes use the following tolerances:

@lax 0.1
@strict 0.000000000000001

Summary

Functions

Whether two numbers are equal (within the given tolerance)

Whether a number is greater than another number, by AT LEAST the tolerance amount.

Whether a number is greater than another number, or equalish.

Whether a number is less than another number, by AT LEAST the tolerance amount.

Whether a number is less than another number, or equalish.

Whether two numbers are not within the given tolerance of each other.

Functions

is_eq_ish(left, right, tolerance \\ 1.0e-5)

(macro)
@spec is_eq_ish(left :: number(), right :: number(), tolerance :: float()) ::
  boolean()

Whether two numbers are equal (within the given tolerance)

Examples

iex> is_eq_ish(0.5, 0.5)
true
iex> is_eq_ish(0.5, 0.5001, @lax)
true
iex> is_eq_ish(0.5, 0.5001, @strict)
false
iex> is_eq_ish(0.5, 0.51)
false

is_gt_ish(left, right, tolerance \\ 1.0e-5)

(macro)
@spec is_gt_ish(left :: number(), right :: number(), tolerance :: float()) ::
  boolean()

Whether a number is greater than another number, by AT LEAST the tolerance amount.

Examples

iex> is_gt_ish(0.5, 0.5)
false
iex> is_gt_ish(0.5, 0.4)
true
iex> is_gt_ish(0.5, 0.6)
false
iex> is_gt_ish(0.5, 0.50000001)
false

is_gte_ish(left, right, tolerance \\ 1.0e-5)

(macro)
@spec is_gte_ish(left :: number(), right :: number(), tolerance :: float()) ::
  boolean()

Whether a number is greater than another number, or equalish.

Examples

iex> is_gte_ish(0.5, 0.5)
true
iex> is_gte_ish(0.5, 0.4)
true
iex> is_gte_ish(0.5, 0.6)
false
iex> is_gte_ish(0.5, 0.50000001)
true

is_lt_ish(left, right, tolerance \\ 1.0e-5)

(macro)
@spec is_lt_ish(left :: number(), right :: number(), tolerance :: float()) ::
  boolean()

Whether a number is less than another number, by AT LEAST the tolerance amount.

Examples

iex> is_lt_ish(0.5, 0.5)
false
iex> is_lt_ish(0.5, 0.4)
false
iex> is_lt_ish(0.5, 0.6)
true
iex> is_lt_ish(0.5, 0.50001, @lax)
false
iex> is_lt_ish(0.5, 0.50001, @strict)
true

is_lte_ish(left, right, tolerance \\ 1.0e-5)

(macro)
@spec is_lte_ish(left :: number(), right :: number(), tolerance :: float()) ::
  boolean()

Whether a number is less than another number, or equalish.

Examples

iex> is_lte_ish(0.5, 0.5)
true
iex> is_lte_ish(0.5, 0.4)
true
iex> is_lte_ish(0.5, 0.6)
false
iex> is_lte_ish(0.5, 0.50000001)
true

is_not_eq_ish(left, right, tolerance \\ 1.0e-5)

(macro)
@spec is_not_eq_ish(left :: number(), right :: number(), tolerance :: float()) ::
  boolean()

Whether two numbers are not within the given tolerance of each other.

Examples

iex> is_not_eq_ish(0.5, 0.5)
false
iex> is_not_eq_ish(0.5, 0.5001, @lax)
false
iex> is_not_eq_ish(0.5, 0.5001, @strict)
true