2

related to:

However with regard to 80 bit IEEE floats (see section 8.2) on an x86

In particular I like the this implementation using a count of representable values between the operands because it scale by default.

One use case would be for numeric approximations where two values approach each other and I need to check to see if they are close enough.


p.s. The implementation language will be D but I can translate. Also an implementation that can automatically handle whatever the underlying type is (for instance if only 64bit real was available) would be ideal.

The current code in use:

Community
  • 1
  • 1
BCS
  • 75,627
  • 68
  • 187
  • 294
  • "I'm wrapping FPs in a units type" (see my answer below,put here so it shows up on BCS' radar) sounds D-ish. Surely at some point you need to know what the data type is for comparison (i.e. unwrap it?). – paxdiablo Dec 10 '08 at 07:05
  • [OT] @Pax: now that's a nice solution!! – BCS Dec 10 '08 at 07:26
  • [OT] http://stackoverflow.uservoice.com/pages/general/suggestions/86757 – BCS Dec 10 '08 at 07:32

2 Answers2

2

Since D has 80-bit reals built in (as far as I can tell), why would you not just use the standard approach of comparing with an epsilon value. This can be a fixed value if you know the rough range in advance, such as US currency:

if (abs (a - b) < 1e-6) // effectively equal

or an acceptable relative error, such as 1 part per million of the average:

if (abs (a - b) < ((a + b) / 2) / 1e6) // effectively equal

Keep in mind I don't know D, the code above is for demonstrative purposes only.

BCS
  • 75,627
  • 68
  • 187
  • 294
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • In my case, I'm wrapping FPs in a units type, so I literally have no special knowledge about the value range. – BCS Dec 10 '08 at 06:56
  • re your comment above: see the new link. The whole thing is a D redux of Boost::SI – BCS Dec 10 '08 at 07:31
0

My current solution is

bool Near(real a, real b, int count = 5)
{
    // Returns the number of mantissa bits which are equal in x and y.
    int i = std.math.feqrel!(real)(a,b);
    return i + count >= real.mant_dig;
}

It gives the number of miss-matched bits in the inputs. I'm not sure how well this will work near powers of 2.

BCS
  • 75,627
  • 68
  • 187
  • 294