1

I want to compare floats like this:

void assertEquals(CGFloat f, CGFloat g) {
  NSCAssert(fabs(f-g) < 0.1);
}

void assertLE(CGFloat f, CGFloat g) {
  NSCAssert(f <= g + 0.1);
}

Is there a tighter bound I can use than 0.1? What's the maximum error that a floating-point comparison can have? Is there a macro, so that I don't hardcode the number?

Kartick Vaddadi
  • 4,818
  • 6
  • 39
  • 55

1 Answers1

4

The maximum rounding error in an IEEE 754 32-bit binary floating point calculation is about 1e31. I calculated it in Java using this program:

public class Test {
  public static void main(String[] args) {
    float biggest = Float.MAX_VALUE;
    float nextBiggest = Math.nextDown(biggest);
    float gap = biggest - nextBiggest;
    System.out.println(gap / 2);
  }
}

It is half the distance between the two biggest finite numbers. You can do a similar calculation in Objective-C for the format you are using. It will be far too big to use for reasonable magnitude calculations.

You really do need to work with relative error, either explicitly or by picking a fixed bound that is appropriate for the magnitudes of your numbers.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • Thanks. Regarding your point about relative error, it's overkill for my use case, which is a test for a UI layout, to assert that one view starts where the previous one ends. I think hardly any of the code I've written needed that level of precision. I'm not controlling a rocket's trajectory, for example. – Kartick Vaddadi Apr 08 '16 at 14:58
  • @KartickVaddadi For UI layout most of your numbers will be within a few orders of magnitude of each other. In that case, I would pick a fixed epsilon that works with those numbers. You will not be able to use the same epsilon if you switch to astrophysics. – Patricia Shanahan Apr 08 '16 at 15:57