File Exchange

image thumbnail

ISEQUALFP: Check equality within floating point precision

version 1.5.0.0 (1.74 KB) by Andrew Davis
Accepts two values, returns a logical indicating if they are equal within floating point precision

1 Download

Updated 22 May 2012

View License

ISEQUALFP Check two values for equality within floating point precision

It is widely known that floating point computation has a fundamental
limitation: not every value can be represented exactly. This can
lead to surprising results for those unfamiliar with this
limitation, especially since 'double' is MATLAB's default numerical
data type.

This function accepts two float values (single or double) or arrays
of floats, and returns a logical value indicating whether they
are equal within floating point precision. Mixed single and double
inputs will be evaluated based on single floating point precision.

Floating point accuracy reference:
http://blogs.mathworks.com/loren/2006/08/23/a-glimpse-into-floating-point-accuracy/

Usage:
yn = isequalfp(a,b)

a,b: floats or arrays of floats to compare

yn: logical scalar result indicating equality

Example:
a = 0.3;
b = 0.1*3;
isequal(a,b) % ans = 0
isequalfp(a,b) % ans = 1
c = a+2*eps(a) % c = 0.3000...
isequalfp(a,c) % ans = 0

See also: EPS, ISEQUAL

Comments and Ratings (5)

Andrew Davis

I think I'll keep the behaviour for different sizes as it is, simply because I think it would confuse me if I was expecting yn=1, but got 0 because one vector was 1 item shorter, for example. Alternatively the function could return 0 but with a warning about the sizes, I suppose, but this is easy enough for people to change if it bugs them.

As for the mixed single and double cases, I like the current behaviour because I had intended for this function to be somewhat generous in calling values equal. This is because I'm never operating near the limits of floating point precision in my day-to-day work. In this way the max() function keeps things somewhat loose in that it returns a single-valued result for mixed single and double inputs. Even, for example, max(single(1), 1+1e6*eps('double')) returns single(1). So the behaviour is:

isequalfp(single(1), 1+1e8*eps('double')) => 1
isequalfp(single(1)+eps('single'), 1) => 1
isequalfp(single(1)+2*eps('single'), 1) => 0

I've updated the documentation to attempt to convey this. Again, thanks for your comments, I'm glad this generated some discussion.

Jan

Jan (view profile)

Fine. Now it works as expected. I'd prefer to get FALSE if the sizes do not match, equivalently to ISEQUAL. But this is a matter of taste.
What do you expect if one input is a SINGLE and the other a DOUBLE? E.g.:
isequalfp(single(1), 1+eps('double'))
isequalfp(single(1)+eps('single'), 1)
Note that "single(1) - (1+eps('double'))" replies: single(-2.2204e-016)
However, the function works as I expect it, it is well documented, useful and usable. Although this is a one-line actually, floating point arithmetics are never trivial. See also: http://en.wikipedia.org/wiki/Floating_point

Andrew Davis

You're right, Jan, that does work better for very disparate arrays. I've updated the file -- thanks for your comment!

Jan

Jan (view profile)

The function fails for: isequalfp([1e17, 1], [1e17, -1]) => true
I think you want:
yn = abs(a - b) <= eps(max(abs(a), abs(b)));

Updates

1.5.0.0

Updated documentation to explain single/double behaviour

1.3.0.0

Syntax modified per Jan's suggestion

1.1.0.0

Description grammar and spacing corrections

MATLAB Release Compatibility
Created with R2011b
Compatible with any release
Platform Compatibility
Windows macOS Linux
Acknowledgements

Inspired: Solve Magic Square

Discover Live Editor

Create scripts with code, output, and formatted text in a single executable document.


Learn About Live Editor