dotnet clr:
[quoted text, click to view] Jason Frank <mabraham36@newsgroup.nospam> wrote: > 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?
I can't see why it wouldn't work to keep using doubles, to be honest. [quoted text, click to view] > 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.
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
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.
[quoted text, click to view] Jason Frank <mabraham36@newsgroup.nospam> wrote: > 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:
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
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] "Jon Skeet [C# MVP]" <skeet@pobox.com> wrote in message news:MPG.1cfda85a9d52769598c1b4@msnews.microsoft.com... > Jason Frank <mabraham36@newsgroup.nospam> wrote: >> 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: > > 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 > If replying to the group, please do not mail me too
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.
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.
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] ""Jeffrey Tan[MSFT]"" <v-jetan@online.microsoft.com> wrote in message news:ujqGn5oYFHA.3336@TK2MSFTNGXA01.phx.gbl... > 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. >
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.
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.
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] ""Jeffrey Tan[MSFT]"" <v-jetan@online.microsoft.com> wrote in message news:$y46nq1YFHA.3508@TK2MSFTNGXA01.phx.gbl... > 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. >
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.
Don't see what you're looking for? Try a search.
|