BigDecimal#hash returns different value for numerically equal numbers #772

ananthakumaran opened this Issue May 26, 2013 · 3 comments


None yet

3 participants



irb(main):003:0>"2").hash =="2.0").hash
=> false
irb(main):004:0>"2") =="2.0")
=> true
=> true


1.9.3p125 :002 >'2').hash =='2.0').hash
 => true
1.9.3p125 :003 >'2') =='2.0')
 => true
1.9.3p125 :004 >'2').eql?('2.0'))
 => true
headius commented May 26, 2013

MRI must be using a different mechanism than us for calculating the hash of BigDecimal. In JRuby, they are both using the JDK's implementation, i.e. java.math.BigDecimal#hashCode. One wonders why the JDK folks did not want equal values to hash the is worth investigating before we go off implementing MRI's behavior. For what it's worth, these are two distinct BigDecimals, since "2" only has one significant figure and "2.0" has two.

atambo commented Jun 22, 2013

According to the BigDecimal#hashCode javadocs:

Note that two BigDecimal objects that are numerically equal but differ in scale (like 2.0 and 2.00) will generally not have the same hash code.

And an easy solution to this would be to call BigDecimal#stripTrailingZeros before calling BigDecimal#hashCode. @headius, does that sound like the right thing to do? If so, I can put together the patch and specs.

headius commented Jun 22, 2013

I'm not comfortable with stripping trailing zeros in general, but stripping just for hashCode purposes might be acceptable. I wish there were a zero-allocation way to get a stripped hashCode from BigDecimal though.

@atambo atambo closed this in 7c8bbf2 Jun 22, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment