-
-
Save yennguyenh/63d5e7a11f354f796b43ada037c4b2c5 to your computer and use it in GitHub Desktop.
Compare relatively equality between 2 float numbers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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