Skip to content

Instantly share code, notes, and snippets.

@yennguyenh
Last active May 9, 2019 10:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yennguyenh/63d5e7a11f354f796b43ada037c4b2c5 to your computer and use it in GitHub Desktop.
Save yennguyenh/63d5e7a11f354f796b43ada037c4b2c5 to your computer and use it in GitHub Desktop.
Compare relatively equality between 2 float numbers
module Math
RELATIVE_TOLERANCE = 1E-9
ABSOLUTE_TOLERANCE = 0.0
##
# returns True if a is close in value to b. False otherwise
#
# source:
# https://github.com/PythonCHB/close_pep/blob/master/isclose.py
# https://www.python.org/dev/peps/pep-0485/#proposed-implementation
#
# Params:
# a: one of the values to be tested
# b: the other value to be tested
# rel_tol=1e-9: The relative tolerance -- the amount of error allowed,
# relative to the absolute value of the larger input values.
# abs_tol=0.0: The minimum absolute tolerance level
# -- useful for comparisons to zero/ numbers near 0/ numbers with very small differences away fom zero.
# NOTES:
# -inf, inf and NaN behave similarly to the IEEE 754 Standard. That
# is, NaN is not close to anything, even itself. inf and -inf are
# only close to themselves.
# The function can be used with any type that supports comparison,
# substratcion and multiplication, including Decimal, Fraction, and
# Complex
# Complex values are compared based on their absolute value.
def self.close?(a, b, rel_tol: RELATIVE_TOLERANCE, abs_tol: ABSOLUTE_TOLERANCE)
raise ArgumentError.new('Arguments must be numeric') unless (a.is_a?(Numeric) && b.is_a?(Numeric))
raise ArgumentError.new('Error tolerance must positive') if (rel_tol < 0.0 || abs_tol < 0.0)
# short-cut exact equality
return true if a == b
# check if any attribute is Infinite
return false if a.infinite? || b.infinite?
# weak comparition - the tolerance is scaled by the larger of 2 values
abs_diff = (a - b).abs
((abs_diff <= (rel_tol * b).abs) ||
(abs_diff <= (rel_tol * a).abs) ||
(abs_diff < abs_tol))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment