Author: Armin Rigo <[email protected]>
Branch: py3.5
Changeset: r87096:0523f9c54a03
Date: 2016-09-13 20:19 +0200
http://bitbucket.org/pypy/pypy/changeset/0523f9c54a03/
Log: math.isclose()
diff --git a/pypy/module/math/__init__.py b/pypy/module/math/__init__.py
--- a/pypy/module/math/__init__.py
+++ b/pypy/module/math/__init__.py
@@ -52,5 +52,6 @@
'erfc' : 'interp_math.erfc',
'gamma' : 'interp_math.gamma',
'lgamma' : 'interp_math.lgamma',
+ 'isclose' : 'interp_math.isclose',
}
diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py
--- a/pypy/module/math/interp_math.py
+++ b/pypy/module/math/interp_math.py
@@ -3,6 +3,7 @@
from rpython.rlib import rfloat
from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
class State:
def __init__(self, space):
@@ -424,3 +425,53 @@
"""Compute the natural logarithm of the gamma function for x."""
return math1(space, rfloat.lgamma, w_x)
+@unwrap_spec(w_rel_tol=WrappedDefault(1e-09), w_abs_tol=WrappedDefault(0.0))
+def isclose(space, w_a, w_b, __kwonly__, w_rel_tol, w_abs_tol):
+ """isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool
+
+Determine whether two floating point numbers are close in value.
+
+ rel_tol
+ maximum difference for being considered "close", relative to the
+ magnitude of the input values
+ abs_tol
+ maximum difference for being considered "close", regardless of the
+ magnitude of the input values
+
+Return True if a is close in value to b, and False otherwise.
+
+For the values to be considered close, the difference between them
+must be smaller than at least one of the tolerances.
+
+-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."""
+ a = _get_double(space, w_a)
+ b = _get_double(space, w_b)
+ rel_tol = _get_double(space, w_rel_tol)
+ abs_tol = _get_double(space, w_abs_tol)
+ #
+ # sanity check on the inputs
+ if rel_tol < 0.0 or abs_tol < 0.0:
+ raise oefmt(space.w_ValueError, "tolerances must be non-negative")
+ #
+ # short circuit exact equality -- needed to catch two infinities of
+ # the same sign. And perhaps speeds things up a bit sometimes.
+ if a == b:
+ return space.w_True
+ #
+ # This catches the case of two infinities of opposite sign, or
+ # one infinity and one finite number. Two infinities of opposite
+ # sign would otherwise have an infinite relative tolerance.
+ # Two infinities of the same sign are caught by the equality check
+ # above.
+ if rfloat.isinf(a) or rfloat.isinf(b):
+ return space.w_False
+ #
+ # now do the regular computation
+ # this is essentially the "weak" test from the Boost library
+ diff = math.fabs(b - a)
+ result = ((diff <= math.fabs(rel_tol * b) or
+ diff <= math.fabs(rel_tol * a)) or
+ diff <= abs_tol)
+ return space.newbool(result)
diff --git a/pypy/module/math/test/test_math.py
b/pypy/module/math/test/test_math.py
--- a/pypy/module/math/test/test_math.py
+++ b/pypy/module/math/test/test_math.py
@@ -343,3 +343,23 @@
assert round(math.lgamma(6.0), 9) == round(math.log(120.0), 9)
assert raises(ValueError, math.gamma, -1)
assert round(math.lgamma(0.5), 9) == round(math.log(math.pi ** 0.5), 9)
+
+ def test_isclose(self):
+ import math
+ assert math.isclose(0, 1) is False
+ assert math.isclose(0, 0.0) is True
+ assert math.isclose(1000.1, 1000.2, abs_tol=0.2) is True
+ assert math.isclose(1000.1, 1000.2, rel_tol=1e-3) is True
+ assert math.isclose(1000.1, 1000.2, abs_tol=0.02) is False
+ assert math.isclose(1000.1, 1000.2, rel_tol=1e-5) is False
+ assert math.isclose(float("inf"), float("inf")) is True
+ assert math.isclose(float("-inf"), float("-inf")) is True
+ assert math.isclose(float("inf"), float("-inf")) is False
+ assert math.isclose(float("-inf"), float("inf")) is False
+ assert math.isclose(float("-inf"), 12.34) is False
+ assert math.isclose(float("-inf"), float("nan")) is False
+ assert math.isclose(float("nan"), 12.34) is False
+ assert math.isclose(float("nan"), float("nan")) is False
+ #
+ raises(TypeError, math.isclose, 0, 1, rel_tol=None)
+ raises(TypeError, math.isclose, 0, 1, abs_tol=None)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit