Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numeric zero,one, WrappedArray.{sum,product} #69

Open
wants to merge 3 commits into
base: 2.12.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/library/scala/collection/mutable/WrappedArray.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,30 @@ object WrappedArray {
case that: ofInt => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
override def sum[B >: Int](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.IntIsIntegral) {
var z = 0
var i = 0
val as = array
while (i < as.length) {
z += as(i)
i += 1
}
z
} else {
super.sum[B]
}
override def product[B >: Int](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.IntIsIntegral) {
var z = 0
var i = 0
val as = array
while (i < as.length) {
z *= as(i)
i += 1
}
z
} else {
super.sum[B]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be super.sum(num)
avoid any implicit that may be in scope, and avoid the implicit scan
and for me - makes it more obvious

}
}

final class ofLong(val array: Array[Long]) extends WrappedArray[Long] with Serializable {
Expand All @@ -190,6 +214,30 @@ object WrappedArray {
case that: ofLong => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
override def sum[B >: Long](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.LongIsIntegral) {
var z = 0L
var i = 0
val as = array
while (i < as.length) {
z += as(i)
i += 1
}
z
} else {
super.sum[B]
}
override def product[B >: Long](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.LongIsIntegral) {
var z = 0L
var i = 0
val as = array
while (i < as.length) {
z *= as(i)
i += 1
}
z
} else {
super.sum[B]
}
}

final class ofFloat(val array: Array[Float]) extends WrappedArray[Float] with Serializable {
Expand All @@ -202,6 +250,30 @@ object WrappedArray {
case that: ofFloat => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
override def sum[B >: Float](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.FloatIsFractional) {
var z = 0f
var i = 0
val as = array
while (i < as.length) {
z += as(i)
i += 1
}
z
} else {
super.sum[B]
}
override def product[B >: Float](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.FloatIsFractional) {
var z = 0f
var i = 0
val as = array
while (i < as.length) {
z *= as(i)
i += 1
}
z
} else {
super.sum[B]
}
}

final class ofDouble(val array: Array[Double]) extends WrappedArray[Double] with Serializable {
Expand All @@ -214,6 +286,30 @@ object WrappedArray {
case that: ofDouble => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
override def sum[B >: Double](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.DoubleIsFractional) {
var z = 0d
var i = 0
val as = array
while (i < as.length) {
z += as(i)
i += 1
}
z
} else {
super.sum[B]
}
override def product[B >: Double](implicit num: Numeric[B]): B = if (num eq scala.math.Numeric.DoubleIsFractional) {
var z = 0d
var i = 0
val as = array
while (i < as.length) {
z *= as(i)
i += 1
}
z
} else {
super.sum[B]
}
}

final class ofBoolean(val array: Array[Boolean]) extends WrappedArray[Boolean] with Serializable {
Expand Down
31 changes: 17 additions & 14 deletions src/library/scala/math/Numeric.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ object Numeric {
def toFloat(x: BigInt): Float = x.floatValue
def toDouble(x: BigInt): Double = x.doubleValue
}
implicit object BigIntIsIntegral extends BigIntIsIntegral with Ordering.BigIntOrdering
implicit object BigIntIsIntegral extends CachedNumeric[BigInt] with BigIntIsIntegral with Ordering.BigIntOrdering

trait IntIsIntegral extends Integral[Int] {
def plus(x: Int, y: Int): Int = x + y
Expand All @@ -59,7 +59,7 @@ object Numeric {
def toFloat(x: Int): Float = x.toFloat
def toDouble(x: Int): Double = x.toDouble
}
implicit object IntIsIntegral extends IntIsIntegral with Ordering.IntOrdering
implicit object IntIsIntegral extends CachedNumeric[Int] with IntIsIntegral with Ordering.IntOrdering

trait ShortIsIntegral extends Integral[Short] {
def plus(x: Short, y: Short): Short = (x + y).toShort
Expand All @@ -74,9 +74,9 @@ object Numeric {
def toFloat(x: Short): Float = x.toFloat
def toDouble(x: Short): Double = x.toDouble
}
implicit object ShortIsIntegral extends ShortIsIntegral with Ordering.ShortOrdering
implicit object ShortIsIntegral extends CachedNumeric[Short] with ShortIsIntegral with Ordering.ShortOrdering

trait ByteIsIntegral extends Integral[Byte] {
trait ByteIsIntegral extends CachedNumeric[Byte] with Integral[Byte] {
def plus(x: Byte, y: Byte): Byte = (x + y).toByte
def minus(x: Byte, y: Byte): Byte = (x - y).toByte
def times(x: Byte, y: Byte): Byte = (x * y).toByte
Expand All @@ -89,7 +89,7 @@ object Numeric {
def toFloat(x: Byte): Float = x.toFloat
def toDouble(x: Byte): Double = x.toDouble
}
implicit object ByteIsIntegral extends ByteIsIntegral with Ordering.ByteOrdering
implicit object ByteIsIntegral extends CachedNumeric[Byte] with ByteIsIntegral with Ordering.ByteOrdering

trait CharIsIntegral extends Integral[Char] {
def plus(x: Char, y: Char): Char = (x + y).toChar
Expand All @@ -104,7 +104,7 @@ object Numeric {
def toFloat(x: Char): Float = x.toFloat
def toDouble(x: Char): Double = x.toDouble
}
implicit object CharIsIntegral extends CharIsIntegral with Ordering.CharOrdering
implicit object CharIsIntegral extends CachedNumeric[Char] with CharIsIntegral with Ordering.CharOrdering

trait LongIsIntegral extends Integral[Long] {
def plus(x: Long, y: Long): Long = x + y
Expand All @@ -119,7 +119,7 @@ object Numeric {
def toFloat(x: Long): Float = x.toFloat
def toDouble(x: Long): Double = x.toDouble
}
implicit object LongIsIntegral extends LongIsIntegral with Ordering.LongOrdering
implicit object LongIsIntegral extends CachedNumeric[Long] with LongIsIntegral with Ordering.LongOrdering

trait FloatIsConflicted extends Numeric[Float] {
def plus(x: Float, y: Float): Float = x + y
Expand All @@ -141,9 +141,8 @@ object Numeric {
def quot(x: Float, y: Float): Float = (BigDecimal(x) quot BigDecimal(y)).floatValue
def rem(x: Float, y: Float): Float = (BigDecimal(x) remainder BigDecimal(y)).floatValue
}
implicit object FloatIsFractional extends FloatIsFractional with Ordering.FloatOrdering
object FloatAsIfIntegral extends FloatAsIfIntegral with Ordering.FloatOrdering {
}
implicit object FloatIsFractional extends CachedNumeric[Float] with FloatIsFractional with Ordering.FloatOrdering
object FloatAsIfIntegral extends CachedNumeric[Float] with FloatAsIfIntegral with Ordering.FloatOrdering

trait DoubleIsConflicted extends Numeric[Double] {
def plus(x: Double, y: Double): Double = x + y
Expand Down Expand Up @@ -188,11 +187,15 @@ object Numeric {

// For Double and BigDecimal we offer implicit Fractional objects, but also one
// which acts like an Integral type, which is useful in NumericRange.
implicit object BigDecimalIsFractional extends BigDecimalIsFractional with Ordering.BigDecimalOrdering
object BigDecimalAsIfIntegral extends BigDecimalAsIfIntegral with Ordering.BigDecimalOrdering
implicit object BigDecimalIsFractional extends CachedNumeric[BigDecimal] with BigDecimalIsFractional with Ordering.BigDecimalOrdering
object BigDecimalAsIfIntegral extends CachedNumeric[BigDecimal] with BigDecimalAsIfIntegral with Ordering.BigDecimalOrdering

implicit object DoubleIsFractional extends DoubleIsFractional with Ordering.DoubleOrdering
object DoubleAsIfIntegral extends DoubleAsIfIntegral with Ordering.DoubleOrdering
implicit object DoubleIsFractional extends CachedNumeric[Double] with DoubleIsFractional with Ordering.DoubleOrdering
object DoubleAsIfIntegral extends CachedNumeric[Double] with DoubleAsIfIntegral with Ordering.DoubleOrdering
private[scala] abstract class CachedNumeric[T] extends Numeric[T] {
override val zero: T = super.zero
override val one: T = super.one
}
}

trait Numeric[T] extends Ordering[T] {
Expand Down