[Python-ideas] Way to check for floating point "closeness"?

Chris Barker - NOAA Federal chris.barker at noaa.gov
Thu Jan 15 06:19:47 CET 2015


On Jan 14, 2015, at 6:14 PM, Ron Adam <ron3200 at gmail.com> wrote:
>
> I would probably write like this.
>
>    def relerr(actual, expected):
>        return abs(actual - expected)/expected
>
> Where expected is a non-zero reference value.

Hmm, there is something to be said about making it clear which is
"expected" -- then that value clearly provides the scale. And you can
document that it can't be zero. And raise an Exception if it does.

> it needs a third value.

Well, a tolerance, yes.

> And then use it this way to measure a resistors tolerance.
>
>    if relerr(218.345, 220) <= 0.05:
>        print("Good")
>    else:
>        print("Bad")

I don't see the advantage at all of this over a simple function API:

Is_close(actual, expected, tolerance)

(Probably with a default tolerance)

> Note that you would never compare to an expected value of zero.

Yup --I like how you can make that clear.  Though sometimes you really
do expect zero. Maybe no need for the same API for that, or an API at
all.

>    relerr(a - b, expected_feet) < tolerance   # relative feet from b

I'm still confused why bother with the relerr function -- why bother?

>    relerr(a - b, ulp)    # percentage of ulp's

I don't think you can define an ulp like that.

> What Chris is looking for is a way to get a closeness function that works most of the time.

Exactly.

> But I don't see how you can do that without specifying some scaler to give it context, and a tolerance.

Yes, you need a tolerance, sure. And the context comes from the values
you are comparing. The only problem is what to do with zero. (And
maybe really near zero).

>     def is_close(a, b, unit, good):
>         return (abs(a - b) / unit) <= good
>
>     is_close(218.345, 220, 1, .05)   # OHMs
>
>     is_close(a, b, ULP, 2)     # ULPs
>
>     is_close(a, b, AU, .001)   # astronomical units

I don't get why it helps to introduce units here. I don't think that's
point (this would all be equally valid with unit less quantities).

And if you want a scale for relative tolerance that is independent of
the values you are checking, that's essentially an absolute tolerance.
I'm not sure it's worth burying that simple calculation in a function.

> I don't see anyway to generalise those with just a function.

Didn't just do that? Except for the Ulps, not sure what to do there,
an ulp is a different way to define a delta.

Unless you mean units aware, but that's really not what this all is about.

> By using objects we can do a bit more.  I seem to recall coming across measurement objects some place.  They keep a bit more context with them.

Sure, there are various  unit/physical quantities objects out there,
many numpy-based. But I think is orthogonal to comparing floating
point numbers.


And a sime floating point comparison function _may_ belong the
standard library, but not a more complex physical quantity system

-Chris


More information about the Python-ideas mailing list