all groups > dotnet clr > may 2005 >
You're in the

dotnet clr

group:

Double comparisons for equality


Re: Double comparisons for equality Jon Skeet [C# MVP]
5/24/2005 12:00:00 AM
dotnet clr:
[quoted text, click to view]

I can't see why it wouldn't work to keep using doubles, to be honest.

[quoted text, click to view]

There are certainly cases where that will happen with arithmetic; I
don't know whether it could happen just from parsing text.

I've posted an example showing it failing before now, but I can't find
it on groups.google.com at the moment, unfortunately.

Here's an example using floats which shows the same kind of behaviour
though:

using System;

class Test
{
static float member;

static void Main()
{
member = Calc();
float local = Calc();
Console.WriteLine(local==member);
}

static float Calc()
{
float d1 = 2.82323f;
float d2 = 2.3f;
return d1*d2;
}

}

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
Double comparisons for equality Jason Frank
5/24/2005 12:00:00 AM
I have an application written in .NET that reads in data as doubles. For
various reasons, I have a need to know if a given double that I'm reading in
is the same as any others that I've seen before. I am currently using a
hashtable to do this, using the double as the key. It seems to be working
fine, but I would like to make myself more confident that this is actually
an ok thing to do. I am aware of a variety of issues around floating-point
precision with arithmetic, but I am not doing any arithmetic. Since a
double is really just a 64-bit pattern, it seems that it should be ok to
compare them for equality, and therefore to use them as the key in a
hashtable. However, one article that I read in my research led me to
believe that this might not be the case, due to registers having more than
64 bits of precision:

http://wesnerm.blogs.com/net_undocumented/2005/01/floating_point__1.html

If it is not ok to compare doubles for equality (even without arithmetic),
what is the generally accepted way to handle this? I could convert them to
byte arrays with the BitConverter and compare those with a custom
comparator, thus getting away from the problem with extra bits in the
registers. Of course, this has performance implications. I could also use
Double.Equals, but I'm not sure how/if that would be different from using
the == operator, and it may be what the hashtable is using anyway.

Thanks for any guidance.

Re: Double comparisons for equality Jon Skeet [C# MVP]
5/24/2005 12:00:00 AM
[quoted text, click to view]

It should be okay for hashtables - by the time the overridden Equals
method is called, and GetHashCode, the extra bits should have
effectively gone, I believe. (I don't see where in the description
above you're using the == operator though - that's where the problems
usually lie.)

The BitConverter route is a reasonable one, but I'd suggest using
BitConverter.DoubleToInt64Bits instead, to give you an Int64 - no need
for a custom comparator that way, and it should be pretty cheap.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
Re: Double comparisons for equality Jason Frank
5/24/2005 5:37:40 PM
Thanks for the reply. It sounds like using a hashtable for doubles is
probably ok, although not guaranteed. I recognize that you'd be reluctant
to give me any absolute advice on the issue, but if I may ask, what would
you do in this circumstance: continue using doubles as the hashtable key, or
convert to Int64?

You are correct in saying that I am not using == in the hashtable instance
that I described below. There are other places in my code, however, where I
am using == to compare two doubles. What I'm gathering from your post is
that it is wise not to do this, and that I should instead write my own
function to do the equality comparison, and use something like the
BitConverter.DoubleToInt64Bits that you mention. In practice, I've never
run into a situation where two doubles that I thought should be equal did
not pass the == test, but if that did happen, I would be in serious trouble.

Thanks again.

[quoted text, click to view]

Re: Double comparisons for equality v-jetan NO[at]SPAM online.microsoft.com (
5/25/2005 9:12:12 AM
Addtionally, I think the article below shows us a good explaination of
floating point in .Net:
"Binary floating point and .NET"
http://www.yoda.arachsys.com/csharp/floatingpoint.html

For your information

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Re: Double comparisons for equality v-jetan NO[at]SPAM online.microsoft.com (
5/27/2005 12:00:00 AM
Hi Jason,

Does our reply make sense to you? If you have any concern, please feel free
to feedback. Thanks

Additionally, for "Jon Skeet [C# MVP]"'s sample, you should change the
project's configuration from debug to release to get the "false" output
value.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Re: Double comparisons for equality Jason Frank
5/27/2005 5:50:00 PM
What I take away from the postings is: I'm probably ok using doubles as keys
in hashtables and in == comparisons, but to be extra confident that nothing
sneaky is going to happen, I should really do something more reliable, such
as using BitConverter.DoubleToInt64Bits. I plan to look into what I think
it would take to upgrade my program to use this technique, and make a
decision.

Thanks for the help.

[quoted text, click to view]

Re: Double comparisons for equality v-jetan NO[at]SPAM online.microsoft.com (
5/28/2005 12:00:00 AM
Hi Jason,

Ok, I am glad this newsgroup can provide you the useful information. If you
have any further concern, please feel free to post. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Re: Double comparisons for equality v-jetan NO[at]SPAM online.microsoft.com (
5/28/2005 12:00:00 AM
Also, I think we'd better no use == for the floating point comparison, just
use subtract operation, and compare the result with a very "little"
number(a tolerance level), just as "Comparing floating point numbers"
section in the link below pointed out:

"One consequence of all of this is that you should very, very rarely be
comparing binary floating point numbers for equality directly. It's usually
fine to compare in terms of greater-than or less-than, but when you're
interested in equality you should always consider whether what you actually
want is near equality: is one number almost the same as another. One simple
way of doing this is to subtract one from the other, use Math.Abs to find
the absolute value of the difference, and then check whether this is lower
than a certain tolerance level. "

"Binary floating point and .NET"
http://www.yoda.arachsys.com/csharp/floatingpoint.html

I think this should be a very important aspect of floating point.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Re: Double comparisons for equality Jason Frank
6/1/2005 4:29:21 PM
In general I agree that it's better to subtract and compare to a small
number than use ==. However, my understanding is that this kind of
"epsilon" comparison is important when doing floating point arithmetic. If
you perform two separate calculations that are arithmetcially equivalent,
you cannot rely on the two results passing the == test. Instead, you should
subtract them and see if the result is "close enough" to zero. In my case,
I am not doing any arithmetic, so it should be sufficient to compare the bit
patterns for equality, which is my understanding of what will happen if I
use BitConverter.DoubleToInt64Bits. If you do not agree, please let me
know.

[quoted text, click to view]

Re: Double comparisons for equality v-jetan NO[at]SPAM online.microsoft.com (
6/2/2005 7:59:44 AM
Yes, currently, I can not see any problem with this. So you may decide to
go with this.

Anyway, if any further help is needed, please feel free to post.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
AddThis Social Bookmark Button