DUnitAssertions: Epsilons

You never want to do exact comparisons on floating-point numbers. They’re finite precision — and 0.1 is a nonrepeating fraction in binary. So 1.1 plus 0.1 does not necessarily equal 1.2.

So float comparisons should always have an epsilon, or fudge factor — something that says “if the difference is only 0.000001, that’s close enough”. That’s why Delphi has the SameValue function (which provides its own reasonable epsilon if you don’t specify your own), and why DUnit has overloads for CheckEquals that take an epsilon.

NUnitLite apparently doesn’t do epsilons, though, so I’m on my own for coming up with a meaningful syntax as I write DUnitAssertions. Here are a few of my brainstorms:

Expect.That(1.1 + 0.1, Tis.EqualTo(1.2, 1E-6));
Expect.That(1.1 + 0.1, Tis.EqualTo(1.2), 1E-6);
Expect.That(1.1 + 0.1, Tis.EqualTo(1.2), Tis.Within(1E-6));
Expect.That(1.1 + 0.1, Tis.EqualTo(1.2), To.Within(1E-6));
Expect.That(1.1 + 0.1, Tis.EqualTo(1.2), Plus.Minus(1E-6));
Expect.That(1.1 + 0.1, Tis.EqualTo(1.2).ToWithin(1E-6));

I like the third one (To.Within) the best, except that it won’t compile (to is a reserved word in Delphi). Obviously I could make it &To but that’s kludgy; a Delphi test framework should compile in Delphi without escaping the method names. Jennie suggested “plus or minus”, which is what prompted Plus.Minus. The last one might work too, although I’d have to fiddle with it.

I’m also not sure how discoverable any of these are. Ideally I’d want something where anyone could sit down with nothing more than the test framework, Intellisense, and one example (Expect.That(2 + 2, Is.EqualTo(4), 'Something is wrong');), and be able to figure the rest out. I already know that’s an impossible goal in Delphi/Win32, because of the issues with enums, but it’s still a decent aim.

Any preferences among these examples? Suggestions?

Leave a Reply

Your email address will not be published. Required fields are marked *