summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRex Kerr <ichoran@gmail.com>2014-11-21 12:14:00 -0800
committerRex Kerr <ichoran@gmail.com>2014-11-21 12:36:56 -0800
commita151449afb247b08d470c91f090f683ebc7ba5a4 (patch)
tree53bf014be32eaf9cffebb7ae31f1dcde24ece642
parentc4df20d29a8d15ef23cf0d10fad56da0791bbbf6 (diff)
downloadscala-a151449afb247b08d470c91f090f683ebc7ba5a4.tar.gz
scala-a151449afb247b08d470c91f090f683ebc7ba5a4.tar.bz2
scala-a151449afb247b08d470c91f090f683ebc7ba5a4.zip
SI-8970 hashCode of BigDecimal and Double do not match
Switched isValidDouble (binary equivalence) to isDecimalDouble (decimal expansion equivalence), as people generally do not care about the slew of extra decimal digits off the end of the binary approximation to a decimal fraction (decimal equivalence is the standard now). Added minimal unit test to verify behavior.
-rw-r--r--src/library/scala/math/BigDecimal.scala4
-rw-r--r--test/junit/scala/math/BigDecimalTest.scala6
2 files changed, 8 insertions, 2 deletions
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index 5a81710986..74a174ea74 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -417,7 +417,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
private final def computeHashCode(): Unit = {
computedHashCode =
if (isWhole && (precision - scale) < BigDecimal.maximumHashScale) toBigInt.hashCode
- else if (isValidDouble) doubleValue.##
+ else if (isDecimalDouble) doubleValue.##
else {
val temp = bigDecimal.stripTrailingZeros
scala.util.hashing.MurmurHash3.mixLast( temp.scaleByPowerOfTen(temp.scale).toBigInteger.hashCode, temp.scale )
@@ -477,7 +477,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
* `isExactDouble`, `isBinaryDouble`, or `isDecimalDouble`, depending on the intended meaning.
* By default, `decimal` creation is used, so `isDecimalDouble` is probably what you want.
*/
- @deprecated("Validity has two distinct meanings. Use `isExactBinaryDouble` or `equivalentToDouble` instead.", "2.11")
+ @deprecated("Validity has distinct meanings. Use `isExactDouble`, `isBinaryDouble`, or `isDecimalDouble` instead.", "2.11")
def isValidDouble = {
val d = toDouble
!d.isInfinity && bigDecimal.compareTo(new BigDec(d)) == 0
diff --git a/test/junit/scala/math/BigDecimalTest.scala b/test/junit/scala/math/BigDecimalTest.scala
index d1ba96fcc8..c7a63da890 100644
--- a/test/junit/scala/math/BigDecimalTest.scala
+++ b/test/junit/scala/math/BigDecimalTest.scala
@@ -222,4 +222,10 @@ class BigDecimalTest {
for (a <- different; b <- different if (a ne b))
assert(a != b, "BigDecimal representations of Double mistakenly conflated")
}
+
+ // Make sure hash code agrees with decimal representation of Double
+ @Test
+ def test_SI8970() {
+ assert((0.1).## == BigDecimal(0.1).##)
+ }
}