[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:
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
> 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.
> 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
And a sime floating point comparison function _may_ belong the
standard library, but not a more complex physical quantity system
More information about the Python-ideas