File Exchange

image thumbnail

ISEQUALFP: Check equality within floating point precision

version 1.5 (1.74 KB) by

Accepts two values, returns a logical indicating if they are equal within floating point precision



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:

yn = isequalfp(a,b)

a,b: floats or arrays of floats to compare

yn: logical scalar result indicating equality

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 Simon

Jan Simon (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:

Andrew Davis

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

Jan Simon

Jan Simon (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)));



Updated documentation to explain single/double behaviour


Syntax modified per Jan's suggestion


Description grammar and spacing corrections

MATLAB Release
MATLAB 7.13 (R2011b)

Inspired: Solve Magic Square

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video

Win prizes and improve your MATLAB skills

Play today