float equality

spir denis.spir at gmail.com
Sat Feb 19 05:17:29 PST 2011


On 02/19/2011 01:21 PM, Jonathan M Davis wrote:
> On Saturday 19 February 2011 04:06:38 spir wrote:
>> Hello,
>>
>> What do you think of this?
>>
>> unittest {
>>       assert(-1.1 + 2.2 == 1.1);          // pass
>>       assert(-1.1 + 2.2 + 3.3 == 4.4);    // pass
>>       assert(-1.1 + 3.3 + 2.2 == 4.4);    // fail
>>       assert(-1.1 + 3.3 == 2.2);          // fail
>> }
>>
>> There is approxEquals in stdlib, right; but shouldn't builtin "==" be
>> consistent anyway?
>
> == is completely consistent. The floating point values in question are _not_
> equal. The problem is that floating point values are inexact. There are values
> which a floating point _cannot_ hold, so it holds the closest value that it can.
> This can quickly and easily lead to having two floating points which seem like
> they should be equal but which aren't. == checks that they're equal, which is
> exactly what it should do (especially in a systems language).

I know about inexact representation, due to bin <--> dec conversion.
Well, about consistency, I meant cases 2 vs 3.

> The thing is, of course, that actual equality sucks for floating point values.
> What's really needed in something like approxEquals. So, approxEquals really
> _should_ be used for comparing floating points and == should only be used on them
> when that is actually what you need (which would be extremely rare). However,
> you can't really make == do approxEquals, because that means that == isn't
> really exact equality anymore and because then it makes it hard to actually
> compare floating point values for equality if that's what you actually want.
> Making == do approxEquals instead would make == inconsistent, not consistent.
>
> This is just one of those cases where the programmer needs to know what they're
> doing and not use ==.

Right, that's what I thought. I guess what people mean in 99% cases is 
"conceptual" equality, right? They don't care about internal representation if 
they are not forced to. So, maybe, default '==' should perform approxEqual if 
needed? And we may have a binEqual just for floats when someone really needs 
binary repr equality? (I cannot impagine a use case, but well...)
What do you think?

I any case, what value should one use as tolerance range for approxEqual?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com



More information about the Digitalmars-d mailing list