Float Comparison Returns False

Loopback elliott.darfink at gmail.com
Sat Jul 9 01:59:03 PDT 2011


On 2011-07-08 04:31, Loopback wrote:
> On 2011-07-08 02:28, bearophile wrote:
>> Loopback:
>>
>>> I do want to ask though what an alternative would be in this case, to
>>> compare the two different values. You mentioned something about
>>> "epsilons" but I have no experience within this field. I would really
>>> appreciate an example or something similar so I could understand your
>>> statement.
>>
>> If you want to use floating point values in your programs then you
>> probably need to know something about floating point representation.
>> This is a good starting point:
>> http://en.wikipedia.org/wiki/Floating_point
>> For your problem there is the feqrel function:
>> http://www.digitalmars.com/d/2.0/phobos/std_math.html#feqrel
>>
>>
>>> From what I can see these are two identical values, I would be more than
>>> glad if someone could explain just what is the difference between these
>>> two "non-equal" values and how make them "equal". Perhaps I should use
>>> ints and long instead since they don't seem to suffer from this
>>> "problem"?
>>
>> Generally in a program you use floating point values only if you can't
>> use integral values (and you don't want to go toward fixed point
>> values, rationals, etc).
>>
>> Bye,
>> bearophile
> I've looked up both approxEqual and feqrel, and the last one seems most
> appropriate, though I cannot use this function without issuing any
> errors. If I use the following code:
>
> writefln("Equality: %s", feqrel(m, 1.73205f));
>
> (From the previous example)
>
> I receive this error with the code:
> Error: function std.math.feqrel!(float).feqrel has no return statement,
> but is expected to return a value of type int
> Error: template instance std.math.feqrel!(float) error instantiating
I weren't able to solve this error so if it's of anyone's interest I
used this function instead;

int feqrel(real a, real b)
{
     if (a==b) return real.mant_dig;
     real diff = fabs(a-b);

     ushort *pa = cast(ushort *)(&a);
     ushort *pb = cast(ushort *)(&b);
     ushort *pd = cast(ushort *)(&diff);

     int bitsdiff = ( ((pa[4]&0x7FFF) + (pb[4]&0x7FFF)-1)>>1) - pd[4];

     if (pd[4]== 0)
     {
	   diff*=0x1p+63;
	   return bitsdiff + real.mant_dig - pd[4];
     }
     if (bitsdiff>0) return bitsdiff+1;
     return bitsdiff==0 ? pa[4]==pb[4] : 0;
}

From: http://www.digitalmars.com/d/archives/digitalmars/D/27873.html


More information about the Digitalmars-d-learn mailing list