Skip to content

Instantly share code, notes, and snippets.

@senevoldsen
Last active May 16, 2019 07:54
Show Gist options
  • Save senevoldsen/ed95034a9d9744a639a69010ff6d9d2b to your computer and use it in GitHub Desktop.
Save senevoldsen/ed95034a9d9744a639a69010ff6d9d2b to your computer and use it in GitHub Desktop.
Float approximation
class Approx(object):
"""
Represents an approximate floating point number. Will compare equal
to any float-convertible type that are within 'tolerance' difference.
>>> 10.0 == Approx(10.0)
True
>>> 10.0 == Approx(10.0001)
False
>>> 10.0 == Approx(10.0000000001)
True
>>> 10.0 == Approx(10.0001, tolerance=1e3)
True
# Forces explicit removal of approximateness
>>> float(Approx(10.0))
Traceback (most recent call last):
RuntimeError: Approx does not permit float conversion. Use .value
# Use .value property to retrieve:
>>> float(Approx(10.0).value)
10.0
"""
def __init__(self, value, tolerance=1e-6):
self._val = float(value)
self._tol = tolerance
def __eq__(self, other):
return abs(self._val - float(other)) <= self._tol
def __ne__(self, other):
return not self == other
def __float__(self):
raise RuntimeError("Approx does not permit float conversion. Use .value")
def __int__(self):
raise RuntimeError("Approx does not permit integer conversion. Use .value")
def __long__(self):
raise RuntimeError("Approx does not permit long integer conversion. Use .value")
def __complex__(self):
raise RuntimeError("Approx does not permit complex conversion. Use .value")
def __coerce__(self):
# Do not allow coercions
return None
@property
def value(self):
return self._val
if __name__ == "__main__":
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment