[Python-ideas] PEP 485: A Function for testing approximate equality
Chris Barker
chris.barker at noaa.gov
Fri Feb 6 01:53:19 CET 2015
On Thu, Feb 5, 2015 at 2:46 PM, Andrew Barnert <abarnert at yahoo.com> wrote:
> >Non-float types
> >---------------
> >
> >The primary use-case is expected to be floating point numbers.
> >However, users may want to compare other numeric types similarly. In
> >theory, it should work for any type that supports ``abs()``,
> >comparisons, and subtraction. The code will be written and tested to
>
> >accommodate these types:
>
> Surely the type also has to support multiplication (or division, if you
> choose to implement it that way) as well, right?
>
yes, multiplication, not sure how I missed that. No division necessary.
> Also, are you sure your implementation doesn't need any explicit
> isinf/isnan checks? You mentioned something about cmath.isnan for complex
> numbers.
>
yeah, there's that. Though it seems to work fine for Fraction and Decimal
so far -- I'm taking a TDD approach -- if it works with a test, I don't
worry about it ;-)
This brings up a bigger issue, that I'm pretty nuetral on:
What to do about duck-typing and various types it may get called with? My
intent was to count of duck typing completely:
1) I'll test with the types I mentioned in the PEP (I need a few more tests
to be rigorous)
2) For any other type, it may work, it may not, and hopefully users will
get an Exception, rather than a spurious result if it doesn't.
I can't possible test with all types, so what else to do?
Would datetime.timedetla be worth explicitly supporting? the concept of a
two datetimes being relatively close doesn't make any sense -- relative to
what???? And abs() fails for datetime already. I'll check timedelta -- it
should work, I think -- abs() does anyway.
I'm a bit on the fence as to whether to do type dispatch for Decimal, as
well -- there are some oddities that may require it.
> Presumably this is just copying assertAlmostEqual and replacing the
> element comparisons with a call to isclose, passing the params along?
yup -- but worth it? Maybe not.
> >How much difference does it make?
>
> >---------------------------------
>
> This section relies on transformations that are valid for reals but not
> for floats. In particular:
does this effect the result? I also assumed a and b are positive and a>b,
just to make all the math easier (and easier to write). I'm not really
trying to do a proper rigorous formal proof here. And it does check out
computationally -- at least with comparing to 1.0, there is no floating
point value that passes some of the test, but not others with a rel_tol of
1-e9 (there is one value that does for 1e-8)
> delta = tol * (a-b)
> >
> >or::
> >
> > delta / tol = (a-b)
>
If a and b are subnormals, the multiplication could underflow to 0, but the
> division won't;
there is no division in the final computation anyway -- I only understand
enough FP to barely pass a class with Kahan, but I think it's OK to do the
derivation with real numbers, and then check the FP consequences with the
actual calculation in this case.
if delta is a very large number, the division could overflow to inf but the
> multiplication won't. (I'm assuming delta < 1.0, of course.) Your later
> substitution has the same issue. I think your ultimate conclusion is right,
> but your proof doesn't really prove it unless you take the extreme cases
> into account.
>
I"m not sure all that needs to be in the PEP anyway -- it's jsut that thre
was a lot of discussion about the various methods, and I had hand-wavingly
said "it doesn't matter for small tolerances" -- so this is simply making
that point for formally.
>The case that uses the arithmetic mean of the two values requires that
> >the value be either added together before dividing by 2, which could
> >result in extra overflow to inf for very large numbers, or require
> >each value to be divided by two before being added together, which
>
> >could result in underflow to -inf for very small numbers.
>
> Dividing by two results in underflow to 0, not -inf.
oops, duh. thanks.
> Also, dividing by two only results in underflow to 0 for two numbers,
> +/-5e-324, and I don't think there's any case where that underflow can
> cause a problem where you wouldn't already underflow to 0 unless tol >=
> 1.0, so I'm not sure this is actually a problem to worry about.
no -- not really -- being a bit pedantic ;-)
> >Relative Tolerance Default
> >--------------------------
>
> This section depends on the fact that a Python float has about 1e-16
> precision.
indeed.
> But technically, that isn't true; it has about sys.float_info.epsilon
> precision, which is up to the implementation; CPython leaves it up to the C
> implementation's double type, and C89 leaves that up to the platform.
> That's why sys.float_info.epsilon is available in the first place--because
> you can't know it a priori.
>
> In practice, I don't know of any modern platforms that don't use IEEE
> double or something close enough, so it's always going to be 2.2e-16-ish.
that's what I was assuming -- but I guess there is always micropython --
does it have machine doubles? I assume the common mobile platfroms do --
but what do I know?
> And I don't think you want the default tolerance to be platform-dependent.
> And I don't think you want to put qualifiers in all the half-dozen places
> you mention the 1e-9. I just think it's worth mentioning in a parenthetical
> somewhere in this paragraph.
>
Good idea.
> >default of 0.0 is selected.
>
> Does that default work properly for the other supported types?
see above for the duck-typing question -- it does work for all the types
I've tested with.
> Maybe it's better to just specify "zero" and leave it up to the
> implementation to do the trivial thing if possible or something more
> complicated if necessary, rather than specifying that it's definitely the
> float 0.0?
>
done in the PEP.
Thanks for the typo fixes.
-Chris
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker at noaa.gov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150205/09e4182d/attachment-0001.html>
More information about the Python-ideas
mailing list