summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-04-13 18:24:48 +0000
committerPaul Phillips <paulp@improving.org>2010-04-13 18:24:48 +0000
commit382dd00508882f15ffd086588903380d7980b35c (patch)
tree157c4c41e2ac7f2418c45fd5db91a06af761879f /src/library
parent27288e3ffe2224bb206e79204542c26a2779223b (diff)
downloadscala-382dd00508882f15ffd086588903380d7980b35c.tar.gz
scala-382dd00508882f15ffd086588903380d7980b35c.tar.bz2
scala-382dd00508882f15ffd086588903380d7980b35c.zip
Some mopping up in equality.
way equals was being handled, and hammered it out. New ==/## tests which covers all types and values. Review by odersky.
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/math/BigDecimal.scala6
-rw-r--r--src/library/scala/math/BigInt.scala2
-rw-r--r--src/library/scala/math/ScalaNumericConversions.scala21
3 files changed, 22 insertions, 7 deletions
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index bb6965fcdc..c4cccd1f52 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -30,6 +30,9 @@ object BigDecimal
private val minCached = -512
private val maxCached = 512
+ val MinLong = BigDecimal(Long.MinValue)
+ val MaxLong = BigDecimal(Long.MaxValue)
+
/** Cache ony for defaultMathContext using BigDecimals in a small range. */
private lazy val cache = new Array[BigDecimal](maxCached - minCached + 1)
@@ -173,12 +176,11 @@ extends ScalaNumber with ScalaNumericConversions
else doubleValue.hashCode()
/** Compares this BigDecimal with the specified value for equality.
- * Will only claim equality with scala.BigDecimal and java.math.BigDecimal.
*/
override def equals (that: Any): Boolean = that match {
case that: BigDecimal => this equals that
case that: BigInt => this.toBigIntExact exists (that equals _)
- case x => unifiedPrimitiveEquals(x)
+ case x => (this <= BigDecimal.MaxLong && this >= BigDecimal.MinLong) && unifiedPrimitiveEquals(x)
}
protected[math] def isWhole = (this remainder 1) == BigDecimal(0)
diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala
index 5267ad8b95..f0988f2934 100644
--- a/src/library/scala/math/BigInt.scala
+++ b/src/library/scala/math/BigInt.scala
@@ -124,7 +124,7 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def equals(that: Any): Boolean = that match {
case that: BigInt => this equals that
case that: BigDecimal => that.toBigIntExact exists (this equals _)
- case x => unifiedPrimitiveEquals(x)
+ case x => (this <= BigInt.MaxLong && this >= BigInt.MinLong) && unifiedPrimitiveEquals(x)
}
protected[math] def isWhole = true
diff --git a/src/library/scala/math/ScalaNumericConversions.scala b/src/library/scala/math/ScalaNumericConversions.scala
index d983595c17..2e754c2584 100644
--- a/src/library/scala/math/ScalaNumericConversions.scala
+++ b/src/library/scala/math/ScalaNumericConversions.scala
@@ -33,15 +33,28 @@ trait ScalaNumericConversions extends ScalaNumber {
else lv.hashCode
}
+ /** Should only be called after all known non-primitive
+ * types have been excluded. This method won't dispatch
+ * anywhere else after checking against the primitives
+ * to avoid infinite recursion between equals and this on
+ * unknown "Number" variants.
+ *
+ * Additionally, this should only be called if the numeric
+ * type is happy to be converted to Long, Float, and Double.
+ * If for instance a BigInt much larger than the Long range is
+ * sent here, it will claim equality with whatever Long is left
+ * in its lower 64 bits. Or a BigDecimal with more precision
+ * than Double can hold: same thing. There's no way given the
+ * interface available here to prevent this error.
+ */
protected def unifiedPrimitiveEquals(x: Any) = x match {
case x: Char => isValidChar && (toInt == x.toInt)
case x: Byte => isValidByte && (toByte == x)
case x: Short => isValidShort && (toShort == x)
case x: Int => isValidInt && (toInt == x)
- case x: Long => toLong == x // XXX
- case x: Float => toFloat == x // XXX
- case x: Double => toDouble == x // XXX
- case x: Number => this equals x
+ case x: Long => toLong == x
+ case x: Float => toFloat == x
+ case x: Double => toDouble == x
case _ => false
}
}