summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/immutable/Range.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2013-11-11 14:20:16 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2013-12-29 17:14:37 +0200
commit4b6a0a999e935a94501da272a12956c024141cb2 (patch)
tree5ca61d3ea3160baeab2dbf07b30cbb5e5eb1b3ba /src/library/scala/collection/immutable/Range.scala
parent6834cc2278ad522e49493b624da95bfa00af1604 (diff)
downloadscala-4b6a0a999e935a94501da272a12956c024141cb2.tar.gz
scala-4b6a0a999e935a94501da272a12956c024141cb2.tar.bz2
scala-4b6a0a999e935a94501da272a12956c024141cb2.zip
SI-7443 Use typeclass instance for {Range,NumericRange}.sum
Previously both Range and NumeriRange used formula for sum of elements of arithmetic series and thus always assumed that provided Numeric is regular one. Bug is now fixed by conservatively checking if Numeric is one of default ones and the formula still holds.
Diffstat (limited to 'src/library/scala/collection/immutable/Range.scala')
-rw-r--r--src/library/scala/collection/immutable/Range.scala21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 00f398a4b0..786b18cd21 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -259,9 +259,24 @@ extends scala.collection.AbstractSeq[Int]
final def contains(x: Int) = isWithinBoundaries(x) && ((x - start) % step == 0)
final override def sum[B >: Int](implicit num: Numeric[B]): Int = {
- if (isEmpty) 0
- else if (numRangeElements == 1) head
- else (numRangeElements.toLong * (head + last) / 2).toInt
+ if (num eq scala.math.Numeric.IntIsIntegral) {
+ // this is normal integer range with usual addition. arithmetic series formula can be used
+ if (isEmpty) 0
+ else if (numRangeElements == 1) head
+ else (numRangeElements.toLong * (head + last) / 2).toInt
+ } else {
+ // user provided custom Numeric, we cannot rely on arithmetic series formula
+ if (isEmpty) num.toInt(num.zero)
+ else {
+ var acc = num.zero
+ var i = head
+ while(i != terminalElement) {
+ acc = num.plus(acc, i)
+ i = i + step
+ }
+ num.toInt(acc)
+ }
+ }
}
override def toIterable = this