When making the PR also update the formatting (the parameters should be emphasized). I think the suggested change to the doc is an improvement, although with floating point arithmetic there are some corner cases:
this is essentially the "weak" test from the Boost library
*/
diff=fabs(b-a);
return (((diff <= fabs(rel_tol*b)) ||
(diff <= fabs(rel_tol*a))) ||
(diff <= abs_tol));
}
@plashchynski I agree the statement is valid if f abs_tol is zero. The way the documentation is written suggest the statement is true in general though (if b=0).
@eendebakpt, I think you misread documentation. It looks like abs_tol disappear in equation of the paragraph, which deals with comparing x to 0, but it's because abs(x) <= rel_tol * abs(x) is valid only in case of abs_tol=0.0 (isclose(x, 0) means the default value of abs_val). Last sentence suggests what to do in this case: "So add an appropriate positive abs_tol argument to the call."
For nonzero abs_tol you must use the generic equation, mentioned right at the beginning of docs: abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol).
Activity
hoodmane commented on Mar 11, 2025
Seems the correction is to add a single word:
Would you mind making a PR?
eendebakpt commented on Mar 11, 2025
When making the PR also update the formatting (the parameters should be emphasized). I think the suggested change to the doc is an improvement, although with floating point arithmetic there are some corner cases:
results in
plashchynski commented on Mar 11, 2025
@eendebakpt it's true because the difference is less than abs_tol:
I think this statement in the documentation holds only for abs_tol being zero (which is the default).
eendebakpt commented on Mar 11, 2025
The relevant code is:
cpython/Modules/mathmodule.c
Lines 3202 to 3211 in ad90c5f
@plashchynski I agree the statement is valid if f abs_tol is zero. The way the documentation is written suggest the statement is true in general though (if b=0).
plashchynski commented on Mar 11, 2025
@eendebakpt imho this statements sounds more like a reason to set abs_tol to a value greater than zero:
cpython/Doc/library/math.rst
Lines 351 to 355 in ad90c5f
plashchynski commented on Mar 11, 2025
Btw, if a = math.nextafter(0, 1) then math.isclose(a, 0) will always be true for any rel_tol > 0:
because:
which is contrary to this statement and to pure mathematics as well.
Is there a policy for such corner cases? Should they be considered and handled?
skirpichev commented on Mar 12, 2025
@eendebakpt, I think you misread documentation. It looks like abs_tol disappear in equation of the paragraph, which deals with comparing x to 0, but it's because abs(x) <= rel_tol * abs(x) is valid only in case of abs_tol=0.0 (isclose(x, 0) means the default value of abs_val). Last sentence suggests what to do in this case: "So add an appropriate positive abs_tol argument to the call."
For nonzero abs_tol you must use the generic equation, mentioned right at the beginning of docs: abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol).
So, in your example:
@hoodmane fix looks good for me. Though, I'm not sure we need such pedancy in docs.
pythongh-131094: Refine math.isclose docs
pythongh-131094: Refine math.isclose docs
gh-131094: Refine `math.isclose` docs (#131139)
pythongh-131094: Refine `math.isclose` docs (pythonGH-131139)
pythongh-131094: Refine `math.isclose` docs (pythonGH-131139)
picnixz commented on Mar 18, 2025
Thank you for the report and the fix!
[3.12] gh-131094: Refine `math.isclose` docs (GH-131139) (#131393)
[3.13] gh-131094: Refine `math.isclose` docs (GH-131139) (#131392)
pythongh-131094: Refine `math.isclose` docs (python#131139)