Code covered by the BSD License  

Highlights from
ISEQUALFP: Check equality within floating point precision

4.0

4.0 | 1 rating Rate this file 9 Downloads (last 30 days) File Size: 1.74 KB File ID: #36734
image thumbnail

ISEQUALFP: Check equality within floating point precision

by

 

16 May 2012 (Updated )

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

| Watch this File

File Information
Description

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

Acknowledgements

This file inspired Solve Magic Square.

Required Products MATLAB
MATLAB release MATLAB 7.13 (R2011b)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (4)
22 May 2012 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.

19 May 2012 Jan Simon

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

18 May 2012 Andrew Davis

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

17 May 2012 Jan Simon

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
17 May 2012

Description grammar and spacing corrections

18 May 2012

Syntax modified per Jan's suggestion

22 May 2012

Updated documentation to explain single/double behaviour

Contact us