diff options
author | Simon Ochsenreither <simon@ochsenreither.de> | 2012-03-27 20:08:30 +0200 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-04-06 11:57:41 -0700 |
commit | e593d8b9ed6d8d98c698d0a7dc47c3341d59c357 (patch) | |
tree | fedd5df5a4592d50c46944dc12a8e3496df78c84 | |
parent | 41c0b0b7b9bd5089e35e1bf32fbcb471a9c78641 (diff) | |
download | scala-e593d8b9ed6d8d98c698d0a7dc47c3341d59c357.tar.gz scala-e593d8b9ed6d8d98c698d0a7dc47c3341d59c357.tar.bz2 scala-e593d8b9ed6d8d98c698d0a7dc47c3341d59c357.zip |
Make NumericRange# O(1) instead of O(n).
It makes me a bit nervous that NumericRange[Int] will
get different wrong values in overflow situations compared
to Range due to the missing toLong though.
It could probably need some investigation if reordering the
operations can rule out wrong values, e. g. only fail when
the fold also fails.
Apart from that, it might make sense to just throw an exception
if an overflow happens instead of silent overflow.
-rw-r--r-- | src/library/scala/collection/immutable/NumericRange.scala | 7 | ||||
-rw-r--r-- | test/files/run/t4658.check | 12 | ||||
-rw-r--r-- | test/files/run/t4658.scala | 14 |
3 files changed, 16 insertions, 17 deletions
diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index 65bd9ab6f2..0966fa035f 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -172,6 +172,13 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable { try containsTyped(x.asInstanceOf[T]) catch { case _: ClassCastException => false } + final override def sum[B >: T](implicit num: Numeric[B]): B = { + import num.Ops + if (isEmpty) this.num fromInt 0 + else if (numRangeElements == 1) head + else ((this.num fromInt numRangeElements) * (head + last) / (this.num fromInt 2)) + } + override lazy val hashCode = super.hashCode() override def equals(other: Any) = other match { case x: NumericRange[_] => diff --git a/test/files/run/t4658.check b/test/files/run/t4658.check index 743b0faee3..bb6405175e 100644 --- a/test/files/run/t4658.check +++ b/test/files/run/t4658.check @@ -19,8 +19,8 @@ Ranges: -30 -10 IntRanges: -Disabled #1 -Disabled #2 +-1073741824 +-1073741824 0 0 55 @@ -39,8 +39,8 @@ Disabled #2 -30 -10 LongRanges: -Disabled #1 -Disabled #2 +2305843008139952128 +-2305843008139952128 0 0 55 @@ -59,8 +59,8 @@ Disabled #2 -30 -10 BigIntRanges: -Disabled #1 -Disabled #2 +2305843008139952128 +-2305843008139952128 0 0 55 diff --git a/test/files/run/t4658.scala b/test/files/run/t4658.scala index e1799fae9b..8c07c50694 100644 --- a/test/files/run/t4658.scala +++ b/test/files/run/t4658.scala @@ -20,22 +20,14 @@ object Test { def numericBigIntRanges = rangeData.map(r => if (r.inclusive) NumericRange.inclusive(BigInt(r.start), BigInt(r.end), BigInt(r.step)) else NumericRange(BigInt(r.start), BigInt(r.end), BigInt(r.step))) def main(args: Array[String]) { - // We drop the first two tests for all ranges which don't have a decent sum implementation, - // because it is just too slow. println("Ranges:") ranges.foreach{range => println(range.sum)} println("IntRanges:") - println("Disabled #1") - println("Disabled #2") - numericIntRanges.drop(2).foreach{range => println(range.sum)} + numericIntRanges.foreach{range => println(range.sum)} println("LongRanges:") - println("Disabled #1") - println("Disabled #2") - numericLongRanges.drop(2).foreach{range => println(range.sum)} + numericLongRanges.foreach{range => println(range.sum)} println("BigIntRanges:") - println("Disabled #1") - println("Disabled #2") - numericBigIntRanges.drop(2).foreach{range => println(range.sum)} + numericBigIntRanges.foreach{range => println(range.sum)} } }
\ No newline at end of file |