[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