title: Issues with checking the equality of two doubles in .NET -- what's wrong with this method?
body: <p>So I'm just going to dive into this issue... I've got a heavily used web application that, for the first time in 2 years, failed doing an equality check on two doubles using the equality function a colleague said he'd also been using for years. </p>
  
  <p>The goal of the function I'm about to paste in here is to compare two double values to 4 digits of precision and return the comparison results. For the sake of illustration, my values are:</p>
  
  <pre><code>Dim double1 As Double = 0.14625000000000002 ' The result of a calculation
  Dim double2 As Double = 0.14625 ' A value that was looked up in a DB
  </code></pre>
  
  <p>If I pass them into this function: </p>
  
  <pre><code>Public Shared Function AreEqual(ByVal double1 As Double, ByVal double2 As Double) As Boolean
  
      Return (CType(double1 * 10000, Long) = CType(double2 * 10000, Long))
  
  End Function
  </code></pre>
  
  <p>the comparison fails. After the multiplication and cast to Long, the comparison ends up being:</p>
  
  <pre><code>Return 1463 = 1462
  </code></pre>
  
  <p>I'm kind of answering my own question here, but I can see that <code>double1</code> is within the precision of a double (17 digits) and the cast is working correctly. </p>
  
  <p>My first real question is: If I change the line above to the following, why does it work correctly (returns <code>True</code>)?</p>
  
  <pre><code>Return (CType(CType(double1, Decimal) * 10000, Long) = _
      CType(CType(double2, Decimal) * 10000, Long))
  </code></pre>
  
  <p>Doesn't <code>Decimal</code> have even more precision, thus the cast to Long should still be <code>1463</code>, and the comparison return <code>False</code>? I think I'm having a brain fart on this stuff...</p>
  
  <p>Secondly, if one were to change this function to make the comparison I'm looking for more accurate or less error prone, would you recommend changing it to something much simpler? For example:</p>
  
  <pre><code>Return (Math.Abs(double1 - double2) &lt; 0.0001)
  </code></pre>
  
  <p>Would I be crazy to try something like:</p>
  
  <pre><code>Return (double1.ToString("N5").Equals(double2.ToString("N5")))
  </code></pre>
  
  <p>(I would never do the above, I'm just curious about your reactions. It would be horribly inefficient in my application.)</p>
  
  <p>Anyway, if someone could shed some light on the difference I'm seeing between casting <code>Double</code>s and <code>Decimal</code>s to <code>Long</code>, that would be great.</p>
  
  <p>Thanks! </p>