File Exchange

## 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

Updated

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

Satya Panuganti

Andrew Davis

### Andrew Davis (view profile)

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: http://en.wikipedia.org/wiki/Floating_point

Andrew Davis

### Andrew Davis (view profile)

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)));

 22 May 2012 1.5 Updated documentation to explain single/double behaviour 18 May 2012 1.3 Syntax modified per Jan's suggestion 17 May 2012 1.1 Description grammar and spacing corrections
##### MATLAB Release
MATLAB 7.13 (R2011b)