title: Implement "tolerant" `equals` & `hashCode` for a class with floating point members
body: <p>I have a class with a <code>float</code> field. For example:</p>
  
  <pre><code>public class MultipleFields {
    final int   count;
    final float floatValue;
  
    public MultipleFields(int count, float floatValue) {
      this.count = count;
      this.floatValue = floatValue;
    }
  
  }
  </code></pre>
  
  <p>I need to be able to compare instances by value.  Now how do I properly implement  <code>equals</code> &amp; <code>hashCode</code>?</p>
  
  <p>The usual way to implement <code>equals</code> and <code>hashCode</code> is to just consider all fields. E.g. Eclipse will generate the following <code>equals</code>:</p>
  
  <pre><code>  public boolean equals(Object obj) {
      // irrelevant type checks removed
      ....
      MultipleFields other = (MultipleFields) obj;
      if (count != other.count)
        return false;
      if (Float.floatToIntBits(floatValue) != Float.floatToIntBits(other.floatValue))
        return false;
      return true;
    }
  </code></pre>
  
  <p>(and a similar <code>hashCode</code>, that essentially computes <code>count* 31 + Float.floatToIntBits(floatValue)</code>).</p>
  
  <p>The problem with this is that my FP values are subject to rounding errors (they may come from user input, from a DB, etc.). So I need a "tolerant" comparison.</p>
  
  <p>The common solution is to compare using an epsilon value (see e.g. <a href="https://stackoverflow.com/questions/21265/comparing-ieee-floats-and-doubles-for-equality">Comparing IEEE floats and doubles for equality</a>). However, I'm not quite certain how I can implement <code>equals</code> using this method, and still have a <code>hashCode</code> that is consisten with <code>equals</code>. </p>
  
  <p>My idea is to define the number of significant digits for comparison, then always round to that number of digits in both <code>equals</code> and <code>hashCode</code>:</p>
  
  <pre><code>long comparisonFloatValue = Math.round(floatValue* (Math.pow(10, RELEVANT_DIGITS)));
  </code></pre>
  
  <p>Then if I replace all uses of <code>floatValue</code> with <code>comparisonFloatValue</code> in  <code>equals</code> and <code>hashCode</code>, I should get a "tolerant" comparison, which is consistent with <code>hashCode</code>.</p>
  
  <ul>
  <li>Will this work?</li>
  <li>Do you see any problems with this approach?</li>
  <li>Is there a better way to do this? It seems rather complicated.</li>
  </ul>