From abd87fb19d4bb7376541e19380acf9c2ec24cf49 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 6 Nov 2009 23:59:26 +0000 Subject: Moved a bunch of classes into the newly created... Moved a bunch of classes into the newly created scala.math package. Created compatibility aliases in the scala package object. --- src/library/scala/BigDecimal.scala | 403 -------------------------- src/library/scala/BigInt.scala | 370 ----------------------- src/library/scala/Equiv.scala | 46 --- src/library/scala/Fractional.scala | 25 -- src/library/scala/Integral.scala | 27 -- src/library/scala/Numeric.scala | 188 ------------ src/library/scala/Ordered.scala | 57 ---- src/library/scala/Ordering.scala | 370 ----------------------- src/library/scala/PartialOrdering.scala | 86 ------ src/library/scala/PartiallyOrdered.scala | 50 ---- src/library/scala/math/BigDecimal.scala | 403 ++++++++++++++++++++++++++ src/library/scala/math/BigInt.scala | 370 +++++++++++++++++++++++ src/library/scala/math/Equiv.scala | 46 +++ src/library/scala/math/Fractional.scala | 25 ++ src/library/scala/math/Integral.scala | 27 ++ src/library/scala/math/Numeric.scala | 188 ++++++++++++ src/library/scala/math/Ordered.scala | 57 ++++ src/library/scala/math/Ordering.scala | 370 +++++++++++++++++++++++ src/library/scala/math/PartialOrdering.scala | 86 ++++++ src/library/scala/math/PartiallyOrdered.scala | 50 ++++ src/library/scala/package.scala | 24 ++ 21 files changed, 1646 insertions(+), 1622 deletions(-) delete mode 100644 src/library/scala/BigDecimal.scala delete mode 100644 src/library/scala/BigInt.scala delete mode 100644 src/library/scala/Equiv.scala delete mode 100644 src/library/scala/Fractional.scala delete mode 100644 src/library/scala/Integral.scala delete mode 100644 src/library/scala/Numeric.scala delete mode 100644 src/library/scala/Ordered.scala delete mode 100644 src/library/scala/Ordering.scala delete mode 100644 src/library/scala/PartialOrdering.scala delete mode 100644 src/library/scala/PartiallyOrdered.scala create mode 100644 src/library/scala/math/BigDecimal.scala create mode 100644 src/library/scala/math/BigInt.scala create mode 100644 src/library/scala/math/Equiv.scala create mode 100644 src/library/scala/math/Fractional.scala create mode 100644 src/library/scala/math/Integral.scala create mode 100644 src/library/scala/math/Numeric.scala create mode 100644 src/library/scala/math/Ordered.scala create mode 100644 src/library/scala/math/Ordering.scala create mode 100644 src/library/scala/math/PartialOrdering.scala create mode 100644 src/library/scala/math/PartiallyOrdered.scala (limited to 'src') diff --git a/src/library/scala/BigDecimal.scala b/src/library/scala/BigDecimal.scala deleted file mode 100644 index b43e4b2a04..0000000000 --- a/src/library/scala/BigDecimal.scala +++ /dev/null @@ -1,403 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - -package scala - -import java.{ lang => jl } -import java.math.{ MathContext, BigDecimal => BigDec } -import scala.collection.immutable.NumericRange - -/** Conversions which present a consistent conversion interface - * across all the numeric types. - */ -trait ScalaNumericConversions extends jl.Number { - def toChar = intValue.toChar - def toByte = byteValue - def toShort = shortValue - def toInt = intValue - def toLong = longValue - def toFloat = floatValue - def toDouble = doubleValue -} - -/** - * @author Stephane Micheloud - * @version 1.0 - * @since 2.7 - */ -object BigDecimal -{ - @serializable - object RoundingMode extends Enumeration(java.math.RoundingMode.values map (_.toString) : _*) { - type RoundingMode = Value - val UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UNNECESSARY = Value - } - - private val minCached = -512 - private val maxCached = 512 - private lazy val cache = new Array[BigDecimal](maxCached - minCached + 1) - - val defaultMathContext = MathContext.UNLIMITED - - /** Constructs a BigDecimal using the java BigDecimal static - * valueOf constructor. - * - * @param d the specified double value - * @return the constructed BigDecimal - */ - def valueOf(d: Double): BigDecimal = apply(BigDec valueOf d) - def valueOf(d: Double, mc: MathContext): BigDecimal = apply(BigDec valueOf d, mc) - - /** Constructs a BigDecimal whose value is equal to that of the - * specified Integer value. - * - * @param i the specified integer value - * @return the constructed BigDecimal - */ - def apply(i: Int): BigDecimal = apply(i, defaultMathContext) - def apply(i: Int, mc: MathContext): BigDecimal = - if (minCached <= i && i <= maxCached) { - val offset = i - minCached - var n = cache(offset) - if (n eq null) { n = new BigDecimal(BigDec.valueOf(i), mc); cache(offset) = n } - n - } else new BigDecimal(BigDec.valueOf(i), mc) - - /** Constructs a BigDecimal whose value is equal to that of the - * specified long value. - * - * @param l the specified long value - * @return the constructed BigDecimal - */ - def apply(l: Long): BigDecimal = - if (minCached <= l && l <= maxCached) apply(l.toInt) - else new BigDecimal(BigDec.valueOf(l), defaultMathContext) - - def apply(l: Long, mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(l, mc), mc) - - /** Constructs a BigDecimal whose unscaled value is equal to that - * of the specified long value. - * - * @param unscaledVal the value - * @param scale the scale - * @return the constructed BigDecimal - */ - def apply(unscaledVal: Long, scale: Int): BigDecimal = - apply(BigInt(unscaledVal), scale) - - def apply(unscaledVal: Long, scale: Int, mc: MathContext): BigDecimal = - apply(BigInt(unscaledVal), scale, mc) - - /** Constructs a BigDecimal whose value is equal to that of the - * specified double value. - * - * @param d the specified Double value - * @return the constructed BigDecimal - */ - def apply(d: Double): BigDecimal = apply(d, defaultMathContext) - // note we don't use the static valueOf because it doesn't let us supply - // a MathContext, but we should be duplicating its logic, modulo caching. - def apply(d: Double, mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(jl.Double.toString(d), mc), mc) - - /** Translates a character array representation of a BigDecimal - * into a BigDecimal. - */ - def apply(x: Array[Char]): BigDecimal = apply(x, defaultMathContext) - def apply(x: Array[Char], mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(x.toString, mc), mc) - - /** Translates the decimal String representation of a BigDecimal - * into a BigDecimal. - */ - def apply(x: String): BigDecimal = apply(x, defaultMathContext) - def apply(x: String, mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(x, mc), mc) - - /** Constructs a BigDecimal whose value is equal to that of the - * specified BigInt value. - * - * @param x the specified BigInt value - * @return the constructed BigDecimal - */ - def apply(x: BigInt): BigDecimal = apply(x, defaultMathContext) - def apply(x: BigInt, mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(x.bigInteger, mc), mc) - - /** Constructs a BigDecimal whose unscaled value is equal to that - * of the specified BigInt value. - * - * @param unscaledVal the specified BigInt value - * @param scale the scale - * @return the constructed BigDecimal - */ - def apply(unscaledVal: BigInt, scale: Int): BigDecimal = apply(unscaledVal, scale, defaultMathContext) - def apply(unscaledVal: BigInt, scale: Int, mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(unscaledVal.bigInteger, scale, mc), mc) - - def apply(bd: BigDec): BigDecimal = apply(bd, defaultMathContext) - def apply(bd: BigDec, mc: MathContext): BigDecimal = new BigDecimal(bd, mc) - - /** Implicit conversion from Int to BigDecimal. */ - implicit def int2bigDecimal(i: Int): BigDecimal = apply(i) - - /** Implicit conversion from Long to BigDecimal. */ - implicit def long2bigDecimal(l: Long): BigDecimal = apply(l) - - /** Implicit conversion from Double to BigDecimal. */ - implicit def double2bigDecimal(d: Double): BigDecimal = valueOf(d, defaultMathContext) -} - -/** - * @author Stephane Micheloud - * @version 1.0 - */ -@serializable -class BigDecimal( - val bigDecimal: BigDec, - val mc: MathContext) -extends jl.Number with ScalaNumericConversions -{ - def this(bigDecimal: BigDec) = this(bigDecimal, BigDecimal.defaultMathContext) - import BigDecimal.RoundingMode._ - - /** Cuts way down on the wrapper noise. */ - private implicit def bigdec2BigDecimal(x: BigDec): BigDecimal = new BigDecimal(x, mc) - - /** Returns the hash code for this BigDecimal. - * Note that this does not use the underlying java object's - * hashCode because we compare BigDecimals with compareTo - * which deems 2 == 2.00, whereas in java these are unequal - * with unequal hashCodes. - */ - override def hashCode(): Int = 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: BigDec => this equals BigDecimal(that) - case _ => false - } - - /** Compares this BigDecimal with the specified BigDecimal for equality. - */ - def equals (that: BigDecimal): Boolean = compare(that) == 0 - - /** Compares this BigDecimal with the specified BigDecimal - */ - def compare (that: BigDecimal): Int = this.bigDecimal compareTo that.bigDecimal - - /** Less-than-or-equals comparison of BigDecimals - */ - def <= (that: BigDecimal): Boolean = compare(that) <= 0 - - /** Greater-than-or-equals comparison of BigDecimals - */ - def >= (that: BigDecimal): Boolean = compare(that) >= 0 - - /** Less-than of BigDecimals - */ - def < (that: BigDecimal): Boolean = compare(that) < 0 - - /** Greater-than comparison of BigDecimals - */ - def > (that: BigDecimal): Boolean = compare(that) > 0 - - /** Addition of BigDecimals - */ - def + (that: BigDecimal): BigDecimal = this.bigDecimal.add(that.bigDecimal, mc) - - /** Subtraction of BigDecimals - */ - def - (that: BigDecimal): BigDecimal = this.bigDecimal.subtract(that.bigDecimal, mc) - - /** Multiplication of BigDecimals - */ - def * (that: BigDecimal): BigDecimal = this.bigDecimal.multiply(that.bigDecimal, mc) - - /** Division of BigDecimals - */ - def / (that: BigDecimal): BigDecimal = this.bigDecimal.divide(that.bigDecimal, mc) - - /** Division and Remainder - returns tuple containing the result of - * divideToIntegralValue and the remainder. - */ - def /% (that: BigDecimal): (BigDecimal, BigDecimal) = - this.bigDecimal.divideAndRemainder(that.bigDecimal, mc) match { - case Array(q, r) => (q, r) - } - - /** Divide to Integral value. - */ - def quot (that: BigDecimal): BigDecimal = - this.bigDecimal.divideToIntegralValue(that.bigDecimal, mc) - - /** Returns the minimum of this and that - */ - def min (that: BigDecimal): BigDecimal = this.bigDecimal min that.bigDecimal - - /** Returns the maximum of this and that - */ - def max (that: BigDecimal): BigDecimal = this.bigDecimal max that.bigDecimal - - /** Remainder after dividing this by that. - */ - def remainder (that: BigDecimal): BigDecimal = this.bigDecimal.remainder(that.bigDecimal, mc) - - /** Returns a BigDecimal whose value is this ** n. - */ - def pow (n: Int): BigDecimal = this.bigDecimal.pow(n, mc) - - /** Returns a BigDecimal whose value is the negation of this BigDecimal - */ - def unary_- : BigDecimal = this.bigDecimal.negate(mc) - - /** Returns the absolute value of this BigDecimal - */ - def abs: BigDecimal = this.bigDecimal abs mc - - /** Returns the sign of this BigDecimal, i.e. - * -1 if it is less than 0, - * +1 if it is greater than 0 - * 0 if it is equal to 0 - */ - def signum: Int = this.bigDecimal.signum() - - /** Returns the precision of this BigDecimal. - */ - def precision: Int = this.bigDecimal.precision() - - /** Returns a BigDecimal rounded according to the MathContext settings. - */ - def round(mc: MathContext): BigDecimal = this.bigDecimal round mc - - /** Returns the scale of this BigDecimal. - */ - def scale: Int = this.bigDecimal.scale() - - /** Returns the size of an ulp, a unit in the last place, of this BigDecimal. - */ - def ulp: BigDecimal = this.bigDecimal.ulp - - /** Returns a new BigDecimal based on the supplied MathContext. - */ - def apply(mc: MathContext): BigDecimal = BigDecimal(this.bigDecimal.toString, mc) - - /** Returns a BigDecimal whose scale is the specified value, and whose value is - * numerically equal to this BigDecimal's. - */ - def setScale(scale: Int): BigDecimal = this.bigDecimal setScale scale - - def setScale(scale: Int, mode: RoundingMode): BigDecimal = - this.bigDecimal.setScale(scale, mode.id) - - /** Converts this BigDecimal to a byte. - * If the BigDecimal is too big to fit in a byte, only the low-order 8 bits are returned. - * Note that this conversion can lose information about the overall magnitude of the - * BigDecimal value as well as return a result with the opposite sign. - */ - override def byteValue = intValue.toByte - - /** Converts this BigDecimal to a short. - * If the BigDecimal is too big to fit in a byte, only the low-order 16 bits are returned. - * Note that this conversion can lose information about the overall magnitude of the - * BigDecimal value as well as return a result with the opposite sign. - */ - override def shortValue = intValue.toShort - - /** Converts this BigDecimal to a char. - * If the BigDecimal is too big to fit in a char, only the low-order 16 bits are returned. - * Note that this conversion can lose information about the overall magnitude of the - * BigDecimal value and that it always returns a positive result. - */ - def charValue = intValue.toChar - - /** Converts this BigDecimal to an int. - * If the BigDecimal is too big to fit in a char, only the low-order 32 bits - * are returned. Note that this conversion can lose information about the - * overall magnitude of the BigDecimal value as well as return a result with - * the opposite sign. - */ - def intValue = this.bigDecimal.intValue - - /** Converts this BigDecimal to a Long. - * If the BigDecimal is too big to fit in a char, only the low-order 64 bits - * are returned. Note that this conversion can lose information about the - * overall magnitude of the BigDecimal value as well as return a result with - * the opposite sign. - */ - def longValue = this.bigDecimal.longValue - - /** Converts this BigDecimal to a float. - * if this BigDecimal has too great a magnitude to represent as a float, - * it will be converted to Float.NEGATIVE_INFINITY or - * Float.POSITIVE_INFINITY as appropriate. - */ - def floatValue = this.bigDecimal.floatValue - - /** Converts this BigDecimal to a Double. - * if this BigDecimal has too great a magnitude to represent as a double, - * it will be converted to Double.NEGATIVE_INFINITY or - * Double.POSITIVE_INFINITY as appropriate. - */ - def doubleValue = this.bigDecimal.doubleValue - - /** This BigDecimal as an exact value. - */ - def toByteExact = bigDecimal.byteValueExact - def toShortExact = bigDecimal.shortValueExact - def toIntExact = bigDecimal.intValueExact - def toLongExact = bigDecimal.longValueExact - - /** Creates a partially constructed NumericRange[BigDecimal] in range - * [start;end), where start is the target BigDecimal. The step - * must be supplied via the "by" method of the returned object in order - * to receive the fully constructed range. For example: - *
-   * val partial = BigDecimal(1.0) to 2.0       // not usable yet
-   * val range = partial by 0.01                // now a NumericRange
-   * val range2 = BigDecimal(0) to 1.0 by 0.01  // all at once of course is fine too
-   * 
- * - * @param end the end value of the range (exclusive) - * @return the partially constructed NumericRange - */ - def until(end: BigDecimal): Range.Partial[BigDecimal, NumericRange.Exclusive[BigDecimal]] = - new Range.Partial(until(end, _)) - - /** Same as the one-argument until, but creates the range immediately. */ - def until(end: BigDecimal, step: BigDecimal) = Range.BigDecimal(this, end, step) - - /** Like until, but inclusive of the end value. */ - def to(end: BigDecimal): Range.Partial[BigDecimal, NumericRange.Inclusive[BigDecimal]] = - new Range.Partial(to(end, _)) - - /** Like until, but inclusive of the end value. */ - def to(end: BigDecimal, step: BigDecimal) = Range.BigDecimal.inclusive(this, end, step) - - /** Converts this BigDecimal to a scala.BigInt. - */ - def toBigInt(): BigInt = new BigInt(this.bigDecimal.toBigInteger()) - - /** Converts this BigDecimal to a scala.BigInt if it - * can be done losslessly, returning Some(BigInt) or None. - */ - def toBigIntExact(): Option[BigInt] = - try Some(new BigInt(this.bigDecimal.toBigIntegerExact())) - catch { case _: ArithmeticException => None } - - /** Returns the decimal String representation of this BigDecimal. - */ - override def toString(): String = this.bigDecimal.toString() - -} diff --git a/src/library/scala/BigInt.scala b/src/library/scala/BigInt.scala deleted file mode 100644 index 9ccd9663a7..0000000000 --- a/src/library/scala/BigInt.scala +++ /dev/null @@ -1,370 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -import java.math.BigInteger -import java.{ lang => jl } - -/** - * @author Martin Odersky - * @version 1.0, 15/07/2003 - * @since 2.1 - */ -object BigInt { - - private val minCached = -1024 - private val maxCached = 1024 - private val cache = new Array[BigInt](maxCached - minCached + 1) - - /** Constructs a BigInt whose value is equal to that of the - * specified integer value. - * - * @param i the specified integer value - * @return the constructed BigInt - */ - def apply(i: Int): BigInt = - if (minCached <= i && i <= maxCached) { - val offset = i - minCached - var n = cache(offset) - if (n eq null) { n = new BigInt(BigInteger.valueOf(i)); cache(offset) = n } - n - } else new BigInt(BigInteger.valueOf(i)) - - /** Constructs a BigInt whose value is equal to that of the - * specified long value. - * - * @param l the specified long value - * @return the constructed BigInt - */ - def apply(l: Long): BigInt = - if (minCached <= l && l <= maxCached) apply(l.toInt) - else new BigInt(BigInteger.valueOf(l)) - - /** Translates a byte array containing the two's-complement binary - * representation of a BigInt into a BigInt. - */ - def apply(x: Array[Byte]): BigInt = - new BigInt(new BigInteger(x)) - - /** Translates the sign-magnitude representation of a BigInt into a BigInt. - */ - def apply(signum: Int, magnitude: Array[Byte]): BigInt = - new BigInt(new BigInteger(signum, magnitude)) - - /** Constructs a randomly generated positive BigInt that is probably prime, - * with the specified bitLength. - */ - def apply(bitlength: Int, certainty: Int, rnd: scala.util.Random): BigInt = - new BigInt(new BigInteger(bitlength, certainty, rnd.self)) - - /** Constructs a randomly generated BigInt, uniformly distributed over the - * range 0 to (2 ^ numBits - 1), inclusive. - * - * @param numbits ... - * @param rnd ... - * @return ... - */ - def apply(numbits: Int, rnd: scala.util.Random): BigInt = - new BigInt(new BigInteger(numbits, rnd.self)) - - /** Translates the decimal String representation of a BigInt into a BigInt. - */ - def apply(x: String): BigInt = - new BigInt(new BigInteger(x)) - - /** Translates the string representation of a BigInt in the - * specified radix into a BigInt. - * - * @param x ... - * @param radix ... - * @return ... - */ - def apply(x: String, radix: Int): BigInt = - new BigInt(new BigInteger(x, radix)) - - /** Returns a positive BigInt that is probably prime, with the specified bitLength. - */ - def probablePrime(bitLength: Int, rnd: scala.util.Random): BigInt = - new BigInt(BigInteger.probablePrime(bitLength, rnd.self)) - - /** Implicit conversion from int to BigInt. - */ - implicit def int2bigInt(i: Int): BigInt = apply(i) - - /** Implicit copnversion from long to BigInt - */ - implicit def long2bigInt(l: Long): BigInt = apply(l) -} - -/** - * @author Martin Odersky - * @version 1.0, 15/07/2003 - */ -@serializable -class BigInt(val bigInteger: BigInteger) extends jl.Number with ScalaNumericConversions -{ - /** Returns the hash code for this BigInt. */ - override def hashCode(): Int = this.bigInteger.hashCode() - - /** Compares this BigInt with the specified value for equality. - */ - override def equals(that: Any): Boolean = that match { - case that: BigInt => this equals that - case that: BigInteger => this equals new BigInt(that) - case _ => false - } - - /** Compares this BigInt with the specified BigInt for equality. - */ - def equals (that: BigInt): Boolean = compare(that) == 0 - - /** Compares this BigInt with the specified BigInt - */ - def compare (that: BigInt): Int = this.bigInteger.compareTo(that.bigInteger) - - /** Less-than-or-equals comparison of BigInts - */ - def <= (that: BigInt): Boolean = compare(that) <= 0 - - /** Greater-than-or-equals comparison of BigInts - */ - def >= (that: BigInt): Boolean = compare(that) >= 0 - - /** Less-than of BigInts - */ - def < (that: BigInt): Boolean = compare(that) < 0 - - /** Greater-than comparison of BigInts - */ - def > (that: BigInt): Boolean = compare(that) > 0 - - /** Addition of BigInts - */ - def + (that: BigInt): BigInt = new BigInt(this.bigInteger.add(that.bigInteger)) - - /** Subtraction of BigInts - */ - def - (that: BigInt): BigInt = new BigInt(this.bigInteger.subtract(that.bigInteger)) - - /** Multiplication of BigInts - */ - def * (that: BigInt): BigInt = new BigInt(this.bigInteger.multiply(that.bigInteger)) - - /** Division of BigInts - */ - def / (that: BigInt): BigInt = new BigInt(this.bigInteger.divide(that.bigInteger)) - - /** Remainder of BigInts - */ - def % (that: BigInt): BigInt = new BigInt(this.bigInteger.remainder(that.bigInteger)) - - /** Returns a pair of two BigInts containing (this / that) and (this % that). - */ - def /% (that: BigInt): (BigInt, BigInt) = { - val dr = this.bigInteger.divideAndRemainder(that.bigInteger) - (new BigInt(dr(0)), new BigInt(dr(1))) - } - - /** Leftshift of BigInt - */ - def << (n: Int): BigInt = new BigInt(this.bigInteger.shiftLeft(n)) - - /** (Signed) rightshift of BigInt - */ - def >> (n: Int): BigInt = new BigInt(this.bigInteger.shiftRight(n)) - - /** Bitwise and of BigInts - */ - def & (that: BigInt): BigInt = new BigInt(this.bigInteger.and(that.bigInteger)) - - /** Bitwise or of BigInts - */ - def | (that: BigInt): BigInt = new BigInt(this.bigInteger.or (that.bigInteger)) - - /** Bitwise exclusive-or of BigInts - */ - def ^ (that: BigInt): BigInt = new BigInt(this.bigInteger.xor(that.bigInteger)) - - /** Bitwise and-not of BigInts. Returns a BigInt whose value is (this & ~that). - */ - def &~ (that: BigInt): BigInt = new BigInt(this.bigInteger.andNot(that.bigInteger)) - - /** Returns the greatest common divisor of abs(this) and abs(that) - */ - def gcd (that: BigInt): BigInt = new BigInt(this.bigInteger.gcd(that.bigInteger)) - - /** Returns a BigInt whose value is (this mod m). - * This method differs from `%' in that it always returns a non-negative BigInt. - */ - def mod (that: BigInt): BigInt = new BigInt(this.bigInteger.mod(that.bigInteger)) - - /** Returns the minimum of this and that - */ - def min (that: BigInt): BigInt = new BigInt(this.bigInteger.min(that.bigInteger)) - - /** Returns the maximum of this and that - */ - def max (that: BigInt): BigInt = new BigInt(this.bigInteger.max(that.bigInteger)) - - /** Returns a BigInt whose value is (this raised to the power of exp). - */ - def pow (exp: Int): BigInt = new BigInt(this.bigInteger.pow(exp)) - - /** Returns a BigInt whose value is - * (this raised to the power of exp modulo m). - */ - def modPow (exp: BigInt, m: BigInt): BigInt = - new BigInt(this.bigInteger.modPow(exp.bigInteger, m.bigInteger)) - - /** Returns a BigInt whose value is (the inverse of this modulo m). - */ - def modInverse (m: BigInt): BigInt = new BigInt(this.bigInteger.modInverse(m.bigInteger)) - - /** Returns a BigInt whose value is the negation of this BigInt - */ - def unary_- : BigInt = new BigInt(this.bigInteger.negate()) - - /** Returns the absolute value of this BigInt - */ - def abs: BigInt = new BigInt(this.bigInteger.abs()) - - /** Returns the sign of this BigInt, i.e. - * -1 if it is less than 0, - * +1 if it is greater than 0 - * 0 if it is equal to 0 - */ - def signum: Int = this.bigInteger.signum() - - /** Returns the bitwise complement of this BigNum - */ - def ~ : BigInt = new BigInt(this.bigInteger.not()) - - /** Returns true if and only if the designated bit is set. - */ - def testBit (n: Int): Boolean = this.bigInteger.testBit(n) - - /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit set. - */ - def setBit (n: Int): BigInt = new BigInt(this.bigInteger.setBit(n)) - - /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit cleared. - */ - def clearBit(n: Int): BigInt = new BigInt(this.bigInteger.clearBit(n)) - - /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit flipped. - */ - def flipBit (n: Int): BigInt = new BigInt(this.bigInteger.flipBit(n)) - - /** Returns the index of the rightmost (lowest-order) one bit in this BigInt - * (the number of zero bits to the right of the rightmost one bit). - */ - def lowestSetBit: Int = this.bigInteger.getLowestSetBit() - - /** Returns the number of bits in the minimal two's-complement representation of this BigInt, - * excluding a sign bit. - */ - def bitLength: Int = this.bigInteger.bitLength() - - /** Returns the number of bits in the two's complement representation of this BigInt - * that differ from its sign bit. - */ - def bitCount: Int = this.bigInteger.bitCount() - - /** Returns true if this BigInt is probably prime, false if it's definitely composite. - * @param certainty a measure of the uncertainty that the caller is willing to tolerate: - * if the call returns true the probability that this BigInt is prime - * exceeds (1 - 1/2 ^ certainty). - * The execution time of this method is proportional to the value of - * this parameter. - */ - def isProbablePrime(certainty: Int) = this.bigInteger.isProbablePrime(certainty) - - /** Converts this BigInt to a byte. - * If the BigInt is too big to fit in a byte, only the low-order 8 bits are returned. - * Note that this conversion can lose information about the overall magnitude of the - * BigInt value as well as return a result with the opposite sign. - */ - override def byteValue = intValue.toByte - - /** Converts this BigInt to a short. - * If the BigInt is too big to fit in a byte, only the low-order 16 bits are returned. - * Note that this conversion can lose information about the overall magnitude of the - * BigInt value as well as return a result with the opposite sign. - */ - override def shortValue = intValue.toShort - - /** Converts this BigInt to a char. - * If the BigInt is too big to fit in a char, only the low-order 16 bits are returned. - * Note that this conversion can lose information about the overall magnitude of the - * BigInt value and that it always returns a positive result. - */ - def charValue = intValue.toChar - - /** Converts this BigInt to an int. - * If the BigInt is too big to fit in a char, only the low-order 32 bits - * are returned. Note that this conversion can lose information about the - * overall magnitude of the BigInt value as well as return a result with - * the opposite sign. - */ - def intValue = this.bigInteger.intValue - - /** Converts this BigInt to a long. - * If the BigInt is too big to fit in a char, only the low-order 64 bits - * are returned. Note that this conversion can lose information about the - * overall magnitude of the BigInt value as well as return a result with - * the opposite sign. - */ - def longValue = this.bigInteger.longValue - - /** Converts this BigInt to a float. - * if this BigInt has too great a magnitude to represent as a float, - * it will be converted to Float.NEGATIVE_INFINITY or - * Float.POSITIVE_INFINITY as appropriate. - */ - def floatValue = this.bigInteger.floatValue - - /** Converts this BigInt to a double. - * if this BigInt has too great a magnitude to represent as a float, - * it will be converted to Float.NEGATIVE_INFINITY or - * Float.POSITIVE_INFINITY as appropriate. - */ - def doubleValue = this.bigInteger.doubleValue - - /** Create a NumericRange[BigInt] in range [start;end) - * with the specified step, where start is the target BigInt. - * - * @param end the end value of the range (exclusive) - * @param step the distance between elements (defaults to 1) - * @return the range - */ - def until(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt(this, end, step) - - /** Like until, but inclusive of the end value. - */ - def to(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt.inclusive(this, end, step) - - /** Returns the decimal String representation of this BigInt. - */ - override def toString(): String = this.bigInteger.toString() - - /** Returns the String representation in the specified radix of this BigInt. - */ - def toString(radix: Int): String = this.bigInteger.toString(radix) - - /** Returns a byte array containing the two's-complement representation of - * this BigInt. The byte array will be in big-endian byte-order: the most - * significant byte is in the zeroth element. The array will contain the - * minimum number of bytes required to represent this BigInt, including at - * least one sign bit. - */ - def toByteArray: Array[Byte] = this.bigInteger.toByteArray() -} diff --git a/src/library/scala/Equiv.scala b/src/library/scala/Equiv.scala deleted file mode 100644 index a13530eb35..0000000000 --- a/src/library/scala/Equiv.scala +++ /dev/null @@ -1,46 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/**

- * A trait for representing equivalence relations. It is important to - * distinguish between a type that can be compared for equality or - * equivalence and a representation of equivalence on some type. This - * trait is for representing the latter. - *

- *

- * An equivalence - * relation is a binary relation on a type. This relation is exposed as - * the equiv method of the Equiv trait. This - * relation must be: - *

- * - * - * @author Geoffrey Washburn - * @version 1.0, 2008-04-03 - * @since 2.7 - */ - -trait Equiv[T] { - /** Returns true iff x is equivalent to - * y. - */ - def equiv(x: T, y: T): Boolean -} diff --git a/src/library/scala/Fractional.scala b/src/library/scala/Fractional.scala deleted file mode 100644 index 46899e5274..0000000000 --- a/src/library/scala/Fractional.scala +++ /dev/null @@ -1,25 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/** - * @since 2.8 - */ -trait Fractional[T] extends Numeric[T] { - def div(x: T, y: T): T - - class FractionalOps(lhs: T) extends Ops(lhs) { - def /(rhs: T) = div(lhs, rhs) - } - override implicit def mkNumericOps(lhs: T): FractionalOps = - new FractionalOps(lhs) -} diff --git a/src/library/scala/Integral.scala b/src/library/scala/Integral.scala deleted file mode 100644 index 63d3ef989c..0000000000 --- a/src/library/scala/Integral.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/** - * @since 2.8 - */ -trait Integral[T] extends Numeric[T] { - def quot(x: T, y: T): T - def rem(x: T, y: T): T - - class IntegralOps(lhs: T) extends Ops(lhs) { - def /(rhs: T) = quot(lhs, rhs) - def %(rhs: T) = rem(lhs, rhs) - def /%(rhs: T) = (quot(lhs, rhs), rem(lhs, rhs)) - } - override implicit def mkNumericOps(lhs: T): IntegralOps = new IntegralOps(lhs) -} diff --git a/src/library/scala/Numeric.scala b/src/library/scala/Numeric.scala deleted file mode 100644 index fa71df6383..0000000000 --- a/src/library/scala/Numeric.scala +++ /dev/null @@ -1,188 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/** - * @since 2.8 - */ -object Numeric { - trait BigIntIsIntegral extends Integral[BigInt] { - def plus(x: BigInt, y: BigInt): BigInt = x + y - def minus(x: BigInt, y: BigInt): BigInt = x - y - def times(x: BigInt, y: BigInt): BigInt = x * y - def quot(x: BigInt, y: BigInt): BigInt = x / y - def rem(x: BigInt, y: BigInt): BigInt = x % y - def negate(x: BigInt): BigInt = -x - def fromInt(x: Int): BigInt = BigInt(x) - def toInt(x: BigInt): Int = x.intValue - def toLong(x: BigInt): Long = x.longValue - def toFloat(x: BigInt): Float = x.longValue.toFloat - def toDouble(x: BigInt): Double = x.longValue.toDouble - } - implicit object BigIntIsIntegral extends BigIntIsIntegral with Ordering.BigIntOrdering - - trait IntIsIntegral extends Integral[Int] { - def plus(x: Int, y: Int): Int = x + y - def minus(x: Int, y: Int): Int = x - y - def times(x: Int, y: Int): Int = x * y - def quot(x: Int, y: Int): Int = x / y - def rem(x: Int, y: Int): Int = x % y - def negate(x: Int): Int = -x - def fromInt(x: Int): Int = x - def toInt(x: Int): Int = x - def toLong(x: Int): Long = x - def toFloat(x: Int): Float = x - def toDouble(x: Int): Double = x - } - implicit object IntIsIntegral extends IntIsIntegral with Ordering.IntOrdering - - trait ShortIsIntegral extends Integral[Short] { - def plus(x: Short, y: Short): Short = (x + y).toShort - def minus(x: Short, y: Short): Short = (x - y).toShort - def times(x: Short, y: Short): Short = (x * y).toShort - def quot(x: Short, y: Short): Short = (x / y).toShort - def rem(x: Short, y: Short): Short = (x % y).toShort - def negate(x: Short): Short = (-x).toShort - def fromInt(x: Int): Short = x.toShort - def toInt(x: Short): Int = x.toInt - def toLong(x: Short): Long = x.toLong - def toFloat(x: Short): Float = x.toFloat - def toDouble(x: Short): Double = x.toDouble - } - implicit object ShortIsIntegral extends ShortIsIntegral with Ordering.ShortOrdering - - trait ByteIsIntegral extends 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 - def quot(x: Byte, y: Byte): Byte = (x / y).toByte - def rem(x: Byte, y: Byte): Byte = (x % y).toByte - def negate(x: Byte): Byte = (-x).toByte - def fromInt(x: Int): Byte = x.toByte - def toInt(x: Byte): Int = x.toInt - def toLong(x: Byte): Long = x.toLong - def toFloat(x: Byte): Float = x.toFloat - def toDouble(x: Byte): Double = x.toDouble - } - implicit object ByteIsIntegral extends ByteIsIntegral with Ordering.ByteOrdering - - trait LongIsIntegral extends Integral[Long] { - def plus(x: Long, y: Long): Long = x + y - def minus(x: Long, y: Long): Long = x - y - def times(x: Long, y: Long): Long = x * y - def quot(x: Long, y: Long): Long = x / y - def rem(x: Long, y: Long): Long = x % y - def negate(x: Long): Long = -x - def fromInt(x: Int): Long = x - def toInt(x: Long): Int = x.toInt - def toLong(x: Long): Long = x - def toFloat(x: Long): Float = x - def toDouble(x: Long): Double = x - } - implicit object LongIsIntegral extends LongIsIntegral with Ordering.LongOrdering - - trait FloatIsFractional extends Fractional[Float] { - def plus(x: Float, y: Float): Float = x + y - def minus(x: Float, y: Float): Float = x - y - def times(x: Float, y: Float): Float = x * y - def div(x: Float, y: Float): Float = x / y - def negate(x: Float): Float = -x - def fromInt(x: Int): Float = x - def toInt(x: Float): Int = x.toInt - def toLong(x: Float): Long = x.toLong - def toFloat(x: Float): Float = x - def toDouble(x: Float): Double = x - } - implicit object FloatIsFractional extends FloatIsFractional with Ordering.FloatOrdering - - trait DoubleIsConflicted extends Numeric[Double] { - def plus(x: Double, y: Double): Double = x + y - def minus(x: Double, y: Double): Double = x - y - def times(x: Double, y: Double): Double = x * y - def negate(x: Double): Double = -x - def fromInt(x: Int): Double = x - def toInt(x: Double): Int = x.toInt - def toLong(x: Double): Long = x.toLong - def toFloat(x: Double): Float = x.toFloat - def toDouble(x: Double): Double = x - } - trait DoubleIsFractional extends DoubleIsConflicted with Fractional[Double] { - def div(x: Double, y: Double): Double = x / y - } - trait DoubleAsIfIntegral extends DoubleIsConflicted with Integral[Double] { - def quot(x: Double, y: Double): Double = (BigDecimal(x) / BigDecimal(y)).doubleValue - def rem(x: Double, y: Double): Double = (BigDecimal(x) remainder BigDecimal(y)).doubleValue - } - - trait BigDecimalIsConflicted extends Numeric[BigDecimal] { - def plus(x: BigDecimal, y: BigDecimal): BigDecimal = x + y - def minus(x: BigDecimal, y: BigDecimal): BigDecimal = x - y - def times(x: BigDecimal, y: BigDecimal): BigDecimal = x * y - def negate(x: BigDecimal): BigDecimal = -x - def fromInt(x: Int): BigDecimal = BigDecimal(x) - def toInt(x: BigDecimal): Int = x.intValue - def toLong(x: BigDecimal): Long = x.longValue - def toFloat(x: BigDecimal): Float = x.floatValue - def toDouble(x: BigDecimal): Double = x.doubleValue - } - - trait BigDecimalIsFractional extends BigDecimalIsConflicted with Fractional[BigDecimal] { - def div(x: BigDecimal, y: BigDecimal): BigDecimal = x / y - } - trait BigDecimalAsIfIntegral extends BigDecimalIsConflicted with Integral[BigDecimal] { - def quot(x: BigDecimal, y: BigDecimal): BigDecimal = x / y - def rem(x: BigDecimal, y: BigDecimal): BigDecimal = x remainder y - } - - // 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 DoubleIsFractional extends DoubleIsFractional with Ordering.DoubleOrdering - object DoubleAsIfIntegral extends DoubleAsIfIntegral with Ordering.DoubleOrdering -} - -trait Numeric[T] extends Ordering[T] { - def plus(x: T, y: T): T - def minus(x: T, y: T): T - def times(x: T, y: T): T - def negate(x: T): T - def fromInt(x: Int): T - def toInt(x: T): Int - def toLong(x: T): Long - def toFloat(x: T): Float - def toDouble(x: T): Double - - def zero = fromInt(0) - def one = fromInt(1) - - def abs(x: T): T = if (lt(x, zero)) negate(x) else x - def signum(x: T): Int = - if (lt(x, zero)) -1 - else if (gt(x, zero)) 1 - else 0 - - class Ops(lhs: T) { - def +(rhs: T) = plus(lhs, rhs) - def -(rhs: T) = minus(lhs, rhs) - def *(rhs: T) = times(lhs, rhs) - def unary_-() = negate(lhs) - def abs(): T = Numeric.this.abs(lhs) - def signum(): Int = Numeric.this.signum(lhs) - def toInt(): Int = Numeric.this.toInt(lhs) - def toLong(): Long = Numeric.this.toLong(lhs) - def toFloat(): Float = Numeric.this.toFloat(lhs) - def toDouble(): Double = Numeric.this.toDouble(lhs) - } - implicit def mkNumericOps(lhs: T): Ops = new Ops(lhs) -} diff --git a/src/library/scala/Ordered.scala b/src/library/scala/Ordered.scala deleted file mode 100644 index 45e10b3a25..0000000000 --- a/src/library/scala/Ordered.scala +++ /dev/null @@ -1,57 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/** A trait for totally ordered data. - * - * Note that since version 2006-07-24 this trait is no longer covariant in a. - * - * It is important that the equals method for an instance of - * Ordered[A] be consistent with the compare method. However, - * due to limitations inherent in the type erasure semantics, - * there is no reasonable way to provide a default implementation - * of equality for instances of Ordered[A]. Therefore, if you need - * to be able to use equality on an instance of Ordered[A] you must - * provide it yourself either when inheiriting or instantiating. - * - * It is important that the hashCode method for an instance of - * Ordered[A] be consistent with the compare method. However, - * it is not possible to provide a sensible default implementation. - * Therefore, if you need to be able compute the hash of an - * instance of Ordered[A] you must provide it yourself either when - * inheiriting or instantiating. - * - * @author Martin Odersky - * @version 1.1, 2006-07-24 - */ -trait Ordered[A] extends java.lang.Comparable[A] { - - /** Result of comparing this with operand that. - * returns x where - * x < 0 iff this < that - * x == 0 iff this == that - * x > 0 iff this > that - */ - def compare(that: A): Int - - def < (that: A): Boolean = (this compare that) < 0 - def > (that: A): Boolean = (this compare that) > 0 - def <= (that: A): Boolean = (this compare that) <= 0 - def >= (that: A): Boolean = (this compare that) >= 0 - def compareTo(that: A): Int = compare(that) -} - -object Ordered { - /** Lens from Ordering[T] to Ordered[T] */ - implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = - new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) } -} diff --git a/src/library/scala/Ordering.scala b/src/library/scala/Ordering.scala deleted file mode 100644 index 223d0bf37d..0000000000 --- a/src/library/scala/Ordering.scala +++ /dev/null @@ -1,370 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -import java.util.Comparator - -/** A trait for representing total orderings. It is important to - * distinguish between a type that has a total order and a representation - * of total ordering on some type. This trait is for representing the - * latter. - * - * A total ordering - * is a binary relation on a type T that is also an equivalence relation - * and partial ordering on values of type T. This relation is exposed as - * the compare method of the Ordering trait. - * This relation must be: - * - * - * @author Geoffrey Washburn - * @version 0.9.5, 2008-04-15 - * @since 2.7 - */ -@serializable -trait Ordering[T] extends Comparator[T] with PartialOrdering[T] { - outer => - - /** An Ordering is defined at all x and y. */ - def tryCompare(x: T, y: T) = Some(compare(x, y)) - - /** Returns a negative integer iff x comes before - * y in the ordering, returns 0 iff x - * is the same in the ordering as y, and returns a - * positive number iff x comes after - * y in the ordering. - */ - def compare(x: T, y: T): Int - - /** Returns true iff x comes before - * y in the ordering. - */ - override def lteq(x: T, y: T): Boolean = compare(x, y) <= 0 - - /** Returns true iff y comes before - * x in the ordering. - */ - override def gteq(x: T, y: T): Boolean = compare(x, y) >= 0 - - /** Returns true iff x comes before - * y in the ordering and is not the same as y. - */ - override def lt(x: T, y: T): Boolean = compare(x, y) < 0 - - /** Returns true iff y comes before - * x in the ordering and is not the same as x. - */ - override def gt(x: T, y: T): Boolean = compare(x, y) > 0 - - /** Returns true iff x is equivalent to - * y in the ordering. - */ - override def equiv(x: T, y: T): Boolean = compare(x, y) == 0 - - /** Returns the argument which comes later in the ordering. */ - def max(x: T, y: T): T = if (gteq(x, y)) x else y - - /** Returns the argument which comes earlier in the ordering. */ - def min(x: T, y: T): T = if (lteq(x, y)) x else y - - override def reverse: Ordering[T] = new Ordering[T]{ - override def reverse = outer - def compare(x: T, y: T) = outer.compare(y, x) - } - - /** Given a function U => T, creates Ordering[U]. */ - def on[U](f: U => T): Ordering[U] = new Ordering[U] { - def compare(x: U, y: U) = outer.compare(f(x), f(y)) - } - - class Ops(lhs: T) { - def <(rhs: T) = lt(lhs, rhs) - def <=(rhs: T) = lteq(lhs, rhs) - def >(rhs: T) = gt(lhs, rhs) - def >=(rhs: T) = gteq(lhs, rhs) - def equiv(rhs: T) = Ordering.this.equiv(lhs, rhs) - def max(rhs: T): T = Ordering.this.max(lhs, rhs) - def min(rhs: T): T = Ordering.this.min(lhs, rhs) - } - implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs) -} - -/** This would conflict with all the nice implicit Orderings - * available, but thanks to the magic of prioritized implicits - * via subclassing we can make Ordered[A] => Ordering[A] only - * turn up if nothing else works. - */ -trait LowPriorityOrderingImplicits { - implicit def ordered[A <: Ordered[A]]: Ordering[A] = new Ordering[A] { - def compare(x: A, y: A) = x.compare(y) - } -} - -object Ordering extends LowPriorityOrderingImplicits { - - def apply[T](implicit ord : Ordering[T]) = ord - - def fromLessThan[T](cmp: (T, T) => Boolean): Ordering[T] = new Ordering[T] { - def compare(x: T, y: T) = if (cmp(x, y)) -1 else if (cmp(y, x)) 1 else 0 - } - - trait UnitOrdering extends Ordering[Unit] { - def compare(x: Unit, y: Unit) = 0 - } - implicit object Unit extends UnitOrdering - - trait BooleanOrdering extends Ordering[Boolean] { - def compare(x: Boolean, y: Boolean) = (x, y) match { - case (false, true) => -1 - case (true, false) => 1 - case _ => 0 - } - } - implicit object Boolean extends BooleanOrdering - - trait ByteOrdering extends Ordering[Byte] { - def compare(x: Byte, y: Byte) = x.toInt - y.toInt - } - implicit object Byte extends ByteOrdering - - trait CharOrdering extends Ordering[Char] { - def compare(x: Char, y: Char) = x.toInt - y.toInt - } - implicit object Char extends CharOrdering - - trait ShortOrdering extends Ordering[Short] { - def compare(x: Short, y: Short) = x.toInt - y.toInt - } - implicit object Short extends ShortOrdering - - trait IntOrdering extends Ordering[Int] { - def compare(x: Int, y: Int) = - if (x < y) -1 - else if (x == y) 0 - else 1 - } - implicit object Int extends IntOrdering - - trait LongOrdering extends Ordering[Long] { - def compare(x: Long, y: Long) = - if (x < y) -1 - else if (x == y) 0 - else 1 - } - implicit object Long extends LongOrdering - - trait FloatOrdering extends Ordering[Float] { - def compare(x: Float, y: Float) = java.lang.Float.compare(x, y) - } - implicit object Float extends FloatOrdering - - trait DoubleOrdering extends Ordering[Double] { - def compare(x: Double, y: Double) = java.lang.Double.compare(x, y) - } - implicit object Double extends DoubleOrdering - - trait BigIntOrdering extends Ordering[BigInt] { - def compare(x: BigInt, y: BigInt) = x.compare(y) - } - implicit object BigInt extends BigIntOrdering - - trait BigDecimalOrdering extends Ordering[BigDecimal] { - def compare(x: BigDecimal, y: BigDecimal) = x.compare(y) - } - implicit object BigDecimal extends BigDecimalOrdering - - trait StringOrdering extends Ordering[String] { - def compare(x: String, y: String) = x.compareTo(y) - } - implicit object String extends StringOrdering - - implicit def Option[T](implicit ord: Ordering[T]) : Ordering[Option[T]] = - new Ordering[Option[T]] { - def compare(x : Option[T], y : Option[T]) = (x, y) match { - case (None, None) => 0 - case (None, _) => -1 - case (_, None) => 1 - case (Some(x), Some(y)) => ord.compare(x, y) - } - } - - implicit def Iterable[T](implicit ord: Ordering[T]): Ordering[Iterable[T]] = - new Ordering[Iterable[T]] { - def compare(x: Iterable[T], y: Iterable[T]): Int = { - val xe = x.iterator - val ye = y.iterator - - while (xe.hasNext && ye.hasNext) { - val res = ord.compare(xe.next, ye.next) - if (res != 0) return res - } - - Boolean.compare(xe.hasNext, ye.hasNext) - } - } - - implicit def Tuple2[T1, T2](implicit ord1: Ordering[T1], ord2: Ordering[T2]): Ordering[(T1, T2)] = - new Ordering[(T1, T2)]{ - def compare(x: (T1, T2), y: (T1, T2)): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - 0 - } - } - - implicit def Tuple3[T1, T2, T3](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3]) : Ordering[(T1, T2, T3)] = - new Ordering[(T1, T2, T3)]{ - def compare(x: (T1, T2, T3), y: (T1, T2, T3)): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - val compare3 = ord3.compare(x._3, y._3) - if (compare3 != 0) return compare3 - 0 - } - } - - implicit def Tuple4[T1, T2, T3, T4](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4]) : Ordering[(T1, T2, T3, T4)] = - new Ordering[(T1, T2, T3, T4)]{ - def compare(x: (T1, T2, T3, T4), y: (T1, T2, T3, T4)): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - val compare3 = ord3.compare(x._3, y._3) - if (compare3 != 0) return compare3 - val compare4 = ord4.compare(x._4, y._4) - if (compare4 != 0) return compare4 - 0 - } - } - - implicit def Tuple5[T1, T2, T3, T4, T5](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5]): Ordering[(T1, T2, T3, T4, T5)] = - new Ordering[(T1, T2, T3, T4, T5)]{ - def compare(x: (T1, T2, T3, T4, T5), y: Tuple5[T1, T2, T3, T4, T5]): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - val compare3 = ord3.compare(x._3, y._3) - if (compare3 != 0) return compare3 - val compare4 = ord4.compare(x._4, y._4) - if (compare4 != 0) return compare4 - val compare5 = ord5.compare(x._5, y._5) - if (compare5 != 0) return compare5 - 0 - } - } - - implicit def Tuple6[T1, T2, T3, T4, T5, T6](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6]): Ordering[(T1, T2, T3, T4, T5, T6)] = - new Ordering[(T1, T2, T3, T4, T5, T6)]{ - def compare(x: (T1, T2, T3, T4, T5, T6), y: (T1, T2, T3, T4, T5, T6)): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - val compare3 = ord3.compare(x._3, y._3) - if (compare3 != 0) return compare3 - val compare4 = ord4.compare(x._4, y._4) - if (compare4 != 0) return compare4 - val compare5 = ord5.compare(x._5, y._5) - if (compare5 != 0) return compare5 - val compare6 = ord6.compare(x._6, y._6) - if (compare6 != 0) return compare6 - 0 - } - } - - implicit def Tuple7[T1, T2, T3, T4, T5, T6, T7](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6], ord7: Ordering[T7]): Ordering[(T1, T2, T3, T4, T5, T6, T7)] = - new Ordering[(T1, T2, T3, T4, T5, T6, T7)]{ - def compare(x: (T1, T2, T3, T4, T5, T6, T7), y: (T1, T2, T3, T4, T5, T6, T7)): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - val compare3 = ord3.compare(x._3, y._3) - if (compare3 != 0) return compare3 - val compare4 = ord4.compare(x._4, y._4) - if (compare4 != 0) return compare4 - val compare5 = ord5.compare(x._5, y._5) - if (compare5 != 0) return compare5 - val compare6 = ord6.compare(x._6, y._6) - if (compare6 != 0) return compare6 - val compare7 = ord7.compare(x._7, y._7) - if (compare7 != 0) return compare7 - 0 - } - } - - implicit def Tuple8[T1, T2, T3, T4, T5, T6, T7, T8](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6], ord7: Ordering[T7], ord8: Ordering[T8]): Ordering[(T1, T2, T3, T4, T5, T6, T7, T8)] = - new Ordering[(T1, T2, T3, T4, T5, T6, T7, T8)]{ - def compare(x: (T1, T2, T3, T4, T5, T6, T7, T8), y: (T1, T2, T3, T4, T5, T6, T7, T8)): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - val compare3 = ord3.compare(x._3, y._3) - if (compare3 != 0) return compare3 - val compare4 = ord4.compare(x._4, y._4) - if (compare4 != 0) return compare4 - val compare5 = ord5.compare(x._5, y._5) - if (compare5 != 0) return compare5 - val compare6 = ord6.compare(x._6, y._6) - if (compare6 != 0) return compare6 - val compare7 = ord7.compare(x._7, y._7) - if (compare7 != 0) return compare7 - val compare8 = ord8.compare(x._8, y._8) - if (compare8 != 0) return compare8 - 0 - } - } - - implicit def Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6], ord7: Ordering[T7], ord8 : Ordering[T8], ord9: Ordering[T9]): Ordering[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] = - new Ordering[(T1, T2, T3, T4, T5, T6, T7, T8, T9)]{ - def compare(x: (T1, T2, T3, T4, T5, T6, T7, T8, T9), y: (T1, T2, T3, T4, T5, T6, T7, T8, T9)): Int = { - val compare1 = ord1.compare(x._1, y._1) - if (compare1 != 0) return compare1 - val compare2 = ord2.compare(x._2, y._2) - if (compare2 != 0) return compare2 - val compare3 = ord3.compare(x._3, y._3) - if (compare3 != 0) return compare3 - val compare4 = ord4.compare(x._4, y._4) - if (compare4 != 0) return compare4 - val compare5 = ord5.compare(x._5, y._5) - if (compare5 != 0) return compare5 - val compare6 = ord6.compare(x._6, y._6) - if (compare6 != 0) return compare6 - val compare7 = ord7.compare(x._7, y._7) - if (compare7 != 0) return compare7 - val compare8 = ord8.compare(x._8, y._8) - if (compare8 != 0) return compare8 - val compare9 = ord9.compare(x._9, y._9) - if (compare9 != 0) return compare9 - 0 - } - } - -} diff --git a/src/library/scala/PartialOrdering.scala b/src/library/scala/PartialOrdering.scala deleted file mode 100644 index cba71410d7..0000000000 --- a/src/library/scala/PartialOrdering.scala +++ /dev/null @@ -1,86 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/**

- * A trait for representing partial orderings. It is important to - * distinguish between a type that has a partial order and a representation - * of partial ordering on some type. This trait is for representing the - * latter. - *

- *

- * A partial ordering - * is a binary relation on a type T that is also an equivalence - * relation on values of type T. This relation is exposed as - * the lteq method of the PartialOrdering trait. - * This relation must be: - *

- * - * - * @author Geoffrey Washburn - * @version 1.0, 2008-04-0-3 - * @since 2.7 - */ - -trait PartialOrdering[T] extends Equiv[T] { - outer => - - /** Result of comparing x with operand y. - * Returns None if operands are not comparable. - * If operands are comparable, returns Some(r) where - * r < 0 iff x < y - * r == 0 iff x == y - * r > 0 iff x > y - */ - def tryCompare(x: T, y: T): Option[Int] - - /** Returns true iff x comes before - * y in the ordering. - */ - def lteq(x: T, y: T): Boolean - - /** Returns true iff y comes before - * x in the ordering. - */ - def gteq(x: T, y: T): Boolean = lteq(y, x) - - /** Returns true iff x comes before - * y in the ordering and is not the same as y. - */ - def lt(x: T, y: T): Boolean = lteq(x, y) && !equiv(x, y) - - /** Returns true iff y comes before - * x in the ordering and is not the same as x. - */ - def gt(x: T, y: T): Boolean = gteq(x, y) && !equiv(x, y) - - /** Returns true iff x is equivalent to - * y in the ordering. - */ - def equiv(x: T, y: T): Boolean = lteq(x,y) && lteq(y,x) - - def reverse : PartialOrdering[T] = new PartialOrdering[T] { - override def reverse = outer - def lteq(x: T, y: T) = outer.lteq(y, x) - def tryCompare(x: T, y: T) = outer.tryCompare(y, x) - } -} diff --git a/src/library/scala/PartiallyOrdered.scala b/src/library/scala/PartiallyOrdered.scala deleted file mode 100644 index b0ddf70220..0000000000 --- a/src/library/scala/PartiallyOrdered.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/** A class for partially ordered data. - * - * @author Martin Odersky - * @version 1.0, 23/04/2004 - */ -trait PartiallyOrdered[+A] { - - /** Result of comparing this with operand that. - * Returns None if operands are not comparable. - * If operands are comparable, returns Some(x) where - * x < 0 iff this < that - * x == 0 iff this == that - * x > 0 iff this > that - */ - def tryCompareTo [B >: A <% PartiallyOrdered[B]](that: B): Option[Int] - - def < [B >: A <% PartiallyOrdered[B]](that: B): Boolean = - (this tryCompareTo that) match { - case Some(x) if x < 0 => true - case _ => false - } - def > [B >: A <% PartiallyOrdered[B]](that: B): Boolean = - (this tryCompareTo that) match { - case Some(x) if x > 0 => true - case _ => false - } - def <= [B >: A <% PartiallyOrdered[B]](that: B): Boolean = - (this tryCompareTo that) match { - case Some(x) if x <= 0 => true - case _ => false - } - def >= [B >: A <% PartiallyOrdered[B]](that: B): Boolean = - (this tryCompareTo that) match { - case Some(x) if x >= 0 => true - case _ => false - } -} diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala new file mode 100644 index 0000000000..677dfa7e17 --- /dev/null +++ b/src/library/scala/math/BigDecimal.scala @@ -0,0 +1,403 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + +package scala.math + +import java.{ lang => jl } +import java.math.{ MathContext, BigDecimal => BigDec } +import scala.collection.immutable.NumericRange + +/** Conversions which present a consistent conversion interface + * across all the numeric types. + */ +trait ScalaNumericConversions extends jl.Number { + def toChar = intValue.toChar + def toByte = byteValue + def toShort = shortValue + def toInt = intValue + def toLong = longValue + def toFloat = floatValue + def toDouble = doubleValue +} + +/** + * @author Stephane Micheloud + * @version 1.0 + * @since 2.7 + */ +object BigDecimal +{ + @serializable + object RoundingMode extends Enumeration(java.math.RoundingMode.values map (_.toString) : _*) { + type RoundingMode = Value + val UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UNNECESSARY = Value + } + + private val minCached = -512 + private val maxCached = 512 + private lazy val cache = new Array[BigDecimal](maxCached - minCached + 1) + + val defaultMathContext = MathContext.UNLIMITED + + /** Constructs a BigDecimal using the java BigDecimal static + * valueOf constructor. + * + * @param d the specified double value + * @return the constructed BigDecimal + */ + def valueOf(d: Double): BigDecimal = apply(BigDec valueOf d) + def valueOf(d: Double, mc: MathContext): BigDecimal = apply(BigDec valueOf d, mc) + + /** Constructs a BigDecimal whose value is equal to that of the + * specified Integer value. + * + * @param i the specified integer value + * @return the constructed BigDecimal + */ + def apply(i: Int): BigDecimal = apply(i, defaultMathContext) + def apply(i: Int, mc: MathContext): BigDecimal = + if (minCached <= i && i <= maxCached) { + val offset = i - minCached + var n = cache(offset) + if (n eq null) { n = new BigDecimal(BigDec.valueOf(i), mc); cache(offset) = n } + n + } else new BigDecimal(BigDec.valueOf(i), mc) + + /** Constructs a BigDecimal whose value is equal to that of the + * specified long value. + * + * @param l the specified long value + * @return the constructed BigDecimal + */ + def apply(l: Long): BigDecimal = + if (minCached <= l && l <= maxCached) apply(l.toInt) + else new BigDecimal(BigDec.valueOf(l), defaultMathContext) + + def apply(l: Long, mc: MathContext): BigDecimal = + new BigDecimal(new BigDec(l, mc), mc) + + /** Constructs a BigDecimal whose unscaled value is equal to that + * of the specified long value. + * + * @param unscaledVal the value + * @param scale the scale + * @return the constructed BigDecimal + */ + def apply(unscaledVal: Long, scale: Int): BigDecimal = + apply(BigInt(unscaledVal), scale) + + def apply(unscaledVal: Long, scale: Int, mc: MathContext): BigDecimal = + apply(BigInt(unscaledVal), scale, mc) + + /** Constructs a BigDecimal whose value is equal to that of the + * specified double value. + * + * @param d the specified Double value + * @return the constructed BigDecimal + */ + def apply(d: Double): BigDecimal = apply(d, defaultMathContext) + // note we don't use the static valueOf because it doesn't let us supply + // a MathContext, but we should be duplicating its logic, modulo caching. + def apply(d: Double, mc: MathContext): BigDecimal = + new BigDecimal(new BigDec(jl.Double.toString(d), mc), mc) + + /** Translates a character array representation of a BigDecimal + * into a BigDecimal. + */ + def apply(x: Array[Char]): BigDecimal = apply(x, defaultMathContext) + def apply(x: Array[Char], mc: MathContext): BigDecimal = + new BigDecimal(new BigDec(x.toString, mc), mc) + + /** Translates the decimal String representation of a BigDecimal + * into a BigDecimal. + */ + def apply(x: String): BigDecimal = apply(x, defaultMathContext) + def apply(x: String, mc: MathContext): BigDecimal = + new BigDecimal(new BigDec(x, mc), mc) + + /** Constructs a BigDecimal whose value is equal to that of the + * specified BigInt value. + * + * @param x the specified BigInt value + * @return the constructed BigDecimal + */ + def apply(x: BigInt): BigDecimal = apply(x, defaultMathContext) + def apply(x: BigInt, mc: MathContext): BigDecimal = + new BigDecimal(new BigDec(x.bigInteger, mc), mc) + + /** Constructs a BigDecimal whose unscaled value is equal to that + * of the specified BigInt value. + * + * @param unscaledVal the specified BigInt value + * @param scale the scale + * @return the constructed BigDecimal + */ + def apply(unscaledVal: BigInt, scale: Int): BigDecimal = apply(unscaledVal, scale, defaultMathContext) + def apply(unscaledVal: BigInt, scale: Int, mc: MathContext): BigDecimal = + new BigDecimal(new BigDec(unscaledVal.bigInteger, scale, mc), mc) + + def apply(bd: BigDec): BigDecimal = apply(bd, defaultMathContext) + def apply(bd: BigDec, mc: MathContext): BigDecimal = new BigDecimal(bd, mc) + + /** Implicit conversion from Int to BigDecimal. */ + implicit def int2bigDecimal(i: Int): BigDecimal = apply(i) + + /** Implicit conversion from Long to BigDecimal. */ + implicit def long2bigDecimal(l: Long): BigDecimal = apply(l) + + /** Implicit conversion from Double to BigDecimal. */ + implicit def double2bigDecimal(d: Double): BigDecimal = valueOf(d, defaultMathContext) +} + +/** + * @author Stephane Micheloud + * @version 1.0 + */ +@serializable +class BigDecimal( + val bigDecimal: BigDec, + val mc: MathContext) +extends jl.Number with ScalaNumericConversions +{ + def this(bigDecimal: BigDec) = this(bigDecimal, BigDecimal.defaultMathContext) + import BigDecimal.RoundingMode._ + + /** Cuts way down on the wrapper noise. */ + private implicit def bigdec2BigDecimal(x: BigDec): BigDecimal = new BigDecimal(x, mc) + + /** Returns the hash code for this BigDecimal. + * Note that this does not use the underlying java object's + * hashCode because we compare BigDecimals with compareTo + * which deems 2 == 2.00, whereas in java these are unequal + * with unequal hashCodes. + */ + override def hashCode(): Int = 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: BigDec => this equals BigDecimal(that) + case _ => false + } + + /** Compares this BigDecimal with the specified BigDecimal for equality. + */ + def equals (that: BigDecimal): Boolean = compare(that) == 0 + + /** Compares this BigDecimal with the specified BigDecimal + */ + def compare (that: BigDecimal): Int = this.bigDecimal compareTo that.bigDecimal + + /** Less-than-or-equals comparison of BigDecimals + */ + def <= (that: BigDecimal): Boolean = compare(that) <= 0 + + /** Greater-than-or-equals comparison of BigDecimals + */ + def >= (that: BigDecimal): Boolean = compare(that) >= 0 + + /** Less-than of BigDecimals + */ + def < (that: BigDecimal): Boolean = compare(that) < 0 + + /** Greater-than comparison of BigDecimals + */ + def > (that: BigDecimal): Boolean = compare(that) > 0 + + /** Addition of BigDecimals + */ + def + (that: BigDecimal): BigDecimal = this.bigDecimal.add(that.bigDecimal, mc) + + /** Subtraction of BigDecimals + */ + def - (that: BigDecimal): BigDecimal = this.bigDecimal.subtract(that.bigDecimal, mc) + + /** Multiplication of BigDecimals + */ + def * (that: BigDecimal): BigDecimal = this.bigDecimal.multiply(that.bigDecimal, mc) + + /** Division of BigDecimals + */ + def / (that: BigDecimal): BigDecimal = this.bigDecimal.divide(that.bigDecimal, mc) + + /** Division and Remainder - returns tuple containing the result of + * divideToIntegralValue and the remainder. + */ + def /% (that: BigDecimal): (BigDecimal, BigDecimal) = + this.bigDecimal.divideAndRemainder(that.bigDecimal, mc) match { + case Array(q, r) => (q, r) + } + + /** Divide to Integral value. + */ + def quot (that: BigDecimal): BigDecimal = + this.bigDecimal.divideToIntegralValue(that.bigDecimal, mc) + + /** Returns the minimum of this and that + */ + def min (that: BigDecimal): BigDecimal = this.bigDecimal min that.bigDecimal + + /** Returns the maximum of this and that + */ + def max (that: BigDecimal): BigDecimal = this.bigDecimal max that.bigDecimal + + /** Remainder after dividing this by that. + */ + def remainder (that: BigDecimal): BigDecimal = this.bigDecimal.remainder(that.bigDecimal, mc) + + /** Returns a BigDecimal whose value is this ** n. + */ + def pow (n: Int): BigDecimal = this.bigDecimal.pow(n, mc) + + /** Returns a BigDecimal whose value is the negation of this BigDecimal + */ + def unary_- : BigDecimal = this.bigDecimal.negate(mc) + + /** Returns the absolute value of this BigDecimal + */ + def abs: BigDecimal = this.bigDecimal abs mc + + /** Returns the sign of this BigDecimal, i.e. + * -1 if it is less than 0, + * +1 if it is greater than 0 + * 0 if it is equal to 0 + */ + def signum: Int = this.bigDecimal.signum() + + /** Returns the precision of this BigDecimal. + */ + def precision: Int = this.bigDecimal.precision() + + /** Returns a BigDecimal rounded according to the MathContext settings. + */ + def round(mc: MathContext): BigDecimal = this.bigDecimal round mc + + /** Returns the scale of this BigDecimal. + */ + def scale: Int = this.bigDecimal.scale() + + /** Returns the size of an ulp, a unit in the last place, of this BigDecimal. + */ + def ulp: BigDecimal = this.bigDecimal.ulp + + /** Returns a new BigDecimal based on the supplied MathContext. + */ + def apply(mc: MathContext): BigDecimal = BigDecimal(this.bigDecimal.toString, mc) + + /** Returns a BigDecimal whose scale is the specified value, and whose value is + * numerically equal to this BigDecimal's. + */ + def setScale(scale: Int): BigDecimal = this.bigDecimal setScale scale + + def setScale(scale: Int, mode: RoundingMode): BigDecimal = + this.bigDecimal.setScale(scale, mode.id) + + /** Converts this BigDecimal to a byte. + * If the BigDecimal is too big to fit in a byte, only the low-order 8 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigDecimal value as well as return a result with the opposite sign. + */ + override def byteValue = intValue.toByte + + /** Converts this BigDecimal to a short. + * If the BigDecimal is too big to fit in a byte, only the low-order 16 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigDecimal value as well as return a result with the opposite sign. + */ + override def shortValue = intValue.toShort + + /** Converts this BigDecimal to a char. + * If the BigDecimal is too big to fit in a char, only the low-order 16 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigDecimal value and that it always returns a positive result. + */ + def charValue = intValue.toChar + + /** Converts this BigDecimal to an int. + * If the BigDecimal is too big to fit in a char, only the low-order 32 bits + * are returned. Note that this conversion can lose information about the + * overall magnitude of the BigDecimal value as well as return a result with + * the opposite sign. + */ + def intValue = this.bigDecimal.intValue + + /** Converts this BigDecimal to a Long. + * If the BigDecimal is too big to fit in a char, only the low-order 64 bits + * are returned. Note that this conversion can lose information about the + * overall magnitude of the BigDecimal value as well as return a result with + * the opposite sign. + */ + def longValue = this.bigDecimal.longValue + + /** Converts this BigDecimal to a float. + * if this BigDecimal has too great a magnitude to represent as a float, + * it will be converted to Float.NEGATIVE_INFINITY or + * Float.POSITIVE_INFINITY as appropriate. + */ + def floatValue = this.bigDecimal.floatValue + + /** Converts this BigDecimal to a Double. + * if this BigDecimal has too great a magnitude to represent as a double, + * it will be converted to Double.NEGATIVE_INFINITY or + * Double.POSITIVE_INFINITY as appropriate. + */ + def doubleValue = this.bigDecimal.doubleValue + + /** This BigDecimal as an exact value. + */ + def toByteExact = bigDecimal.byteValueExact + def toShortExact = bigDecimal.shortValueExact + def toIntExact = bigDecimal.intValueExact + def toLongExact = bigDecimal.longValueExact + + /** Creates a partially constructed NumericRange[BigDecimal] in range + * [start;end), where start is the target BigDecimal. The step + * must be supplied via the "by" method of the returned object in order + * to receive the fully constructed range. For example: + *
+   * val partial = BigDecimal(1.0) to 2.0       // not usable yet
+   * val range = partial by 0.01                // now a NumericRange
+   * val range2 = BigDecimal(0) to 1.0 by 0.01  // all at once of course is fine too
+   * 
+ * + * @param end the end value of the range (exclusive) + * @return the partially constructed NumericRange + */ + def until(end: BigDecimal): Range.Partial[BigDecimal, NumericRange.Exclusive[BigDecimal]] = + new Range.Partial(until(end, _)) + + /** Same as the one-argument until, but creates the range immediately. */ + def until(end: BigDecimal, step: BigDecimal) = Range.BigDecimal(this, end, step) + + /** Like until, but inclusive of the end value. */ + def to(end: BigDecimal): Range.Partial[BigDecimal, NumericRange.Inclusive[BigDecimal]] = + new Range.Partial(to(end, _)) + + /** Like until, but inclusive of the end value. */ + def to(end: BigDecimal, step: BigDecimal) = Range.BigDecimal.inclusive(this, end, step) + + /** Converts this BigDecimal to a scala.BigInt. + */ + def toBigInt(): BigInt = new BigInt(this.bigDecimal.toBigInteger()) + + /** Converts this BigDecimal to a scala.BigInt if it + * can be done losslessly, returning Some(BigInt) or None. + */ + def toBigIntExact(): Option[BigInt] = + try Some(new BigInt(this.bigDecimal.toBigIntegerExact())) + catch { case _: ArithmeticException => None } + + /** Returns the decimal String representation of this BigDecimal. + */ + override def toString(): String = this.bigDecimal.toString() + +} diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala new file mode 100644 index 0000000000..5415a29489 --- /dev/null +++ b/src/library/scala/math/BigInt.scala @@ -0,0 +1,370 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +import java.math.BigInteger +import java.{ lang => jl } + +/** + * @author Martin Odersky + * @version 1.0, 15/07/2003 + * @since 2.1 + */ +object BigInt { + + private val minCached = -1024 + private val maxCached = 1024 + private val cache = new Array[BigInt](maxCached - minCached + 1) + + /** Constructs a BigInt whose value is equal to that of the + * specified integer value. + * + * @param i the specified integer value + * @return the constructed BigInt + */ + def apply(i: Int): BigInt = + if (minCached <= i && i <= maxCached) { + val offset = i - minCached + var n = cache(offset) + if (n eq null) { n = new BigInt(BigInteger.valueOf(i)); cache(offset) = n } + n + } else new BigInt(BigInteger.valueOf(i)) + + /** Constructs a BigInt whose value is equal to that of the + * specified long value. + * + * @param l the specified long value + * @return the constructed BigInt + */ + def apply(l: Long): BigInt = + if (minCached <= l && l <= maxCached) apply(l.toInt) + else new BigInt(BigInteger.valueOf(l)) + + /** Translates a byte array containing the two's-complement binary + * representation of a BigInt into a BigInt. + */ + def apply(x: Array[Byte]): BigInt = + new BigInt(new BigInteger(x)) + + /** Translates the sign-magnitude representation of a BigInt into a BigInt. + */ + def apply(signum: Int, magnitude: Array[Byte]): BigInt = + new BigInt(new BigInteger(signum, magnitude)) + + /** Constructs a randomly generated positive BigInt that is probably prime, + * with the specified bitLength. + */ + def apply(bitlength: Int, certainty: Int, rnd: scala.util.Random): BigInt = + new BigInt(new BigInteger(bitlength, certainty, rnd.self)) + + /** Constructs a randomly generated BigInt, uniformly distributed over the + * range 0 to (2 ^ numBits - 1), inclusive. + * + * @param numbits ... + * @param rnd ... + * @return ... + */ + def apply(numbits: Int, rnd: scala.util.Random): BigInt = + new BigInt(new BigInteger(numbits, rnd.self)) + + /** Translates the decimal String representation of a BigInt into a BigInt. + */ + def apply(x: String): BigInt = + new BigInt(new BigInteger(x)) + + /** Translates the string representation of a BigInt in the + * specified radix into a BigInt. + * + * @param x ... + * @param radix ... + * @return ... + */ + def apply(x: String, radix: Int): BigInt = + new BigInt(new BigInteger(x, radix)) + + /** Returns a positive BigInt that is probably prime, with the specified bitLength. + */ + def probablePrime(bitLength: Int, rnd: scala.util.Random): BigInt = + new BigInt(BigInteger.probablePrime(bitLength, rnd.self)) + + /** Implicit conversion from int to BigInt. + */ + implicit def int2bigInt(i: Int): BigInt = apply(i) + + /** Implicit copnversion from long to BigInt + */ + implicit def long2bigInt(l: Long): BigInt = apply(l) +} + +/** + * @author Martin Odersky + * @version 1.0, 15/07/2003 + */ +@serializable +class BigInt(val bigInteger: BigInteger) extends jl.Number with ScalaNumericConversions +{ + /** Returns the hash code for this BigInt. */ + override def hashCode(): Int = this.bigInteger.hashCode() + + /** Compares this BigInt with the specified value for equality. + */ + override def equals(that: Any): Boolean = that match { + case that: BigInt => this equals that + case that: BigInteger => this equals new BigInt(that) + case _ => false + } + + /** Compares this BigInt with the specified BigInt for equality. + */ + def equals (that: BigInt): Boolean = compare(that) == 0 + + /** Compares this BigInt with the specified BigInt + */ + def compare (that: BigInt): Int = this.bigInteger.compareTo(that.bigInteger) + + /** Less-than-or-equals comparison of BigInts + */ + def <= (that: BigInt): Boolean = compare(that) <= 0 + + /** Greater-than-or-equals comparison of BigInts + */ + def >= (that: BigInt): Boolean = compare(that) >= 0 + + /** Less-than of BigInts + */ + def < (that: BigInt): Boolean = compare(that) < 0 + + /** Greater-than comparison of BigInts + */ + def > (that: BigInt): Boolean = compare(that) > 0 + + /** Addition of BigInts + */ + def + (that: BigInt): BigInt = new BigInt(this.bigInteger.add(that.bigInteger)) + + /** Subtraction of BigInts + */ + def - (that: BigInt): BigInt = new BigInt(this.bigInteger.subtract(that.bigInteger)) + + /** Multiplication of BigInts + */ + def * (that: BigInt): BigInt = new BigInt(this.bigInteger.multiply(that.bigInteger)) + + /** Division of BigInts + */ + def / (that: BigInt): BigInt = new BigInt(this.bigInteger.divide(that.bigInteger)) + + /** Remainder of BigInts + */ + def % (that: BigInt): BigInt = new BigInt(this.bigInteger.remainder(that.bigInteger)) + + /** Returns a pair of two BigInts containing (this / that) and (this % that). + */ + def /% (that: BigInt): (BigInt, BigInt) = { + val dr = this.bigInteger.divideAndRemainder(that.bigInteger) + (new BigInt(dr(0)), new BigInt(dr(1))) + } + + /** Leftshift of BigInt + */ + def << (n: Int): BigInt = new BigInt(this.bigInteger.shiftLeft(n)) + + /** (Signed) rightshift of BigInt + */ + def >> (n: Int): BigInt = new BigInt(this.bigInteger.shiftRight(n)) + + /** Bitwise and of BigInts + */ + def & (that: BigInt): BigInt = new BigInt(this.bigInteger.and(that.bigInteger)) + + /** Bitwise or of BigInts + */ + def | (that: BigInt): BigInt = new BigInt(this.bigInteger.or (that.bigInteger)) + + /** Bitwise exclusive-or of BigInts + */ + def ^ (that: BigInt): BigInt = new BigInt(this.bigInteger.xor(that.bigInteger)) + + /** Bitwise and-not of BigInts. Returns a BigInt whose value is (this & ~that). + */ + def &~ (that: BigInt): BigInt = new BigInt(this.bigInteger.andNot(that.bigInteger)) + + /** Returns the greatest common divisor of abs(this) and abs(that) + */ + def gcd (that: BigInt): BigInt = new BigInt(this.bigInteger.gcd(that.bigInteger)) + + /** Returns a BigInt whose value is (this mod m). + * This method differs from `%' in that it always returns a non-negative BigInt. + */ + def mod (that: BigInt): BigInt = new BigInt(this.bigInteger.mod(that.bigInteger)) + + /** Returns the minimum of this and that + */ + def min (that: BigInt): BigInt = new BigInt(this.bigInteger.min(that.bigInteger)) + + /** Returns the maximum of this and that + */ + def max (that: BigInt): BigInt = new BigInt(this.bigInteger.max(that.bigInteger)) + + /** Returns a BigInt whose value is (this raised to the power of exp). + */ + def pow (exp: Int): BigInt = new BigInt(this.bigInteger.pow(exp)) + + /** Returns a BigInt whose value is + * (this raised to the power of exp modulo m). + */ + def modPow (exp: BigInt, m: BigInt): BigInt = + new BigInt(this.bigInteger.modPow(exp.bigInteger, m.bigInteger)) + + /** Returns a BigInt whose value is (the inverse of this modulo m). + */ + def modInverse (m: BigInt): BigInt = new BigInt(this.bigInteger.modInverse(m.bigInteger)) + + /** Returns a BigInt whose value is the negation of this BigInt + */ + def unary_- : BigInt = new BigInt(this.bigInteger.negate()) + + /** Returns the absolute value of this BigInt + */ + def abs: BigInt = new BigInt(this.bigInteger.abs()) + + /** Returns the sign of this BigInt, i.e. + * -1 if it is less than 0, + * +1 if it is greater than 0 + * 0 if it is equal to 0 + */ + def signum: Int = this.bigInteger.signum() + + /** Returns the bitwise complement of this BigNum + */ + def ~ : BigInt = new BigInt(this.bigInteger.not()) + + /** Returns true if and only if the designated bit is set. + */ + def testBit (n: Int): Boolean = this.bigInteger.testBit(n) + + /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit set. + */ + def setBit (n: Int): BigInt = new BigInt(this.bigInteger.setBit(n)) + + /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit cleared. + */ + def clearBit(n: Int): BigInt = new BigInt(this.bigInteger.clearBit(n)) + + /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit flipped. + */ + def flipBit (n: Int): BigInt = new BigInt(this.bigInteger.flipBit(n)) + + /** Returns the index of the rightmost (lowest-order) one bit in this BigInt + * (the number of zero bits to the right of the rightmost one bit). + */ + def lowestSetBit: Int = this.bigInteger.getLowestSetBit() + + /** Returns the number of bits in the minimal two's-complement representation of this BigInt, + * excluding a sign bit. + */ + def bitLength: Int = this.bigInteger.bitLength() + + /** Returns the number of bits in the two's complement representation of this BigInt + * that differ from its sign bit. + */ + def bitCount: Int = this.bigInteger.bitCount() + + /** Returns true if this BigInt is probably prime, false if it's definitely composite. + * @param certainty a measure of the uncertainty that the caller is willing to tolerate: + * if the call returns true the probability that this BigInt is prime + * exceeds (1 - 1/2 ^ certainty). + * The execution time of this method is proportional to the value of + * this parameter. + */ + def isProbablePrime(certainty: Int) = this.bigInteger.isProbablePrime(certainty) + + /** Converts this BigInt to a byte. + * If the BigInt is too big to fit in a byte, only the low-order 8 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value as well as return a result with the opposite sign. + */ + override def byteValue = intValue.toByte + + /** Converts this BigInt to a short. + * If the BigInt is too big to fit in a byte, only the low-order 16 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value as well as return a result with the opposite sign. + */ + override def shortValue = intValue.toShort + + /** Converts this BigInt to a char. + * If the BigInt is too big to fit in a char, only the low-order 16 bits are returned. + * Note that this conversion can lose information about the overall magnitude of the + * BigInt value and that it always returns a positive result. + */ + def charValue = intValue.toChar + + /** Converts this BigInt to an int. + * If the BigInt is too big to fit in a char, only the low-order 32 bits + * are returned. Note that this conversion can lose information about the + * overall magnitude of the BigInt value as well as return a result with + * the opposite sign. + */ + def intValue = this.bigInteger.intValue + + /** Converts this BigInt to a long. + * If the BigInt is too big to fit in a char, only the low-order 64 bits + * are returned. Note that this conversion can lose information about the + * overall magnitude of the BigInt value as well as return a result with + * the opposite sign. + */ + def longValue = this.bigInteger.longValue + + /** Converts this BigInt to a float. + * if this BigInt has too great a magnitude to represent as a float, + * it will be converted to Float.NEGATIVE_INFINITY or + * Float.POSITIVE_INFINITY as appropriate. + */ + def floatValue = this.bigInteger.floatValue + + /** Converts this BigInt to a double. + * if this BigInt has too great a magnitude to represent as a float, + * it will be converted to Float.NEGATIVE_INFINITY or + * Float.POSITIVE_INFINITY as appropriate. + */ + def doubleValue = this.bigInteger.doubleValue + + /** Create a NumericRange[BigInt] in range [start;end) + * with the specified step, where start is the target BigInt. + * + * @param end the end value of the range (exclusive) + * @param step the distance between elements (defaults to 1) + * @return the range + */ + def until(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt(this, end, step) + + /** Like until, but inclusive of the end value. + */ + def to(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt.inclusive(this, end, step) + + /** Returns the decimal String representation of this BigInt. + */ + override def toString(): String = this.bigInteger.toString() + + /** Returns the String representation in the specified radix of this BigInt. + */ + def toString(radix: Int): String = this.bigInteger.toString(radix) + + /** Returns a byte array containing the two's-complement representation of + * this BigInt. The byte array will be in big-endian byte-order: the most + * significant byte is in the zeroth element. The array will contain the + * minimum number of bytes required to represent this BigInt, including at + * least one sign bit. + */ + def toByteArray: Array[Byte] = this.bigInteger.toByteArray() +} diff --git a/src/library/scala/math/Equiv.scala b/src/library/scala/math/Equiv.scala new file mode 100644 index 0000000000..3cdee42ee7 --- /dev/null +++ b/src/library/scala/math/Equiv.scala @@ -0,0 +1,46 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +/**

+ * A trait for representing equivalence relations. It is important to + * distinguish between a type that can be compared for equality or + * equivalence and a representation of equivalence on some type. This + * trait is for representing the latter. + *

+ *

+ * An equivalence + * relation is a binary relation on a type. This relation is exposed as + * the equiv method of the Equiv trait. This + * relation must be: + *

+ * + * + * @author Geoffrey Washburn + * @version 1.0, 2008-04-03 + * @since 2.7 + */ + +trait Equiv[T] { + /** Returns true iff x is equivalent to + * y. + */ + def equiv(x: T, y: T): Boolean +} diff --git a/src/library/scala/math/Fractional.scala b/src/library/scala/math/Fractional.scala new file mode 100644 index 0000000000..4c7c09fe73 --- /dev/null +++ b/src/library/scala/math/Fractional.scala @@ -0,0 +1,25 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +/** + * @since 2.8 + */ +trait Fractional[T] extends Numeric[T] { + def div(x: T, y: T): T + + class FractionalOps(lhs: T) extends Ops(lhs) { + def /(rhs: T) = div(lhs, rhs) + } + override implicit def mkNumericOps(lhs: T): FractionalOps = + new FractionalOps(lhs) +} diff --git a/src/library/scala/math/Integral.scala b/src/library/scala/math/Integral.scala new file mode 100644 index 0000000000..cdace45fb0 --- /dev/null +++ b/src/library/scala/math/Integral.scala @@ -0,0 +1,27 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +/** + * @since 2.8 + */ +trait Integral[T] extends Numeric[T] { + def quot(x: T, y: T): T + def rem(x: T, y: T): T + + class IntegralOps(lhs: T) extends Ops(lhs) { + def /(rhs: T) = quot(lhs, rhs) + def %(rhs: T) = rem(lhs, rhs) + def /%(rhs: T) = (quot(lhs, rhs), rem(lhs, rhs)) + } + override implicit def mkNumericOps(lhs: T): IntegralOps = new IntegralOps(lhs) +} diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala new file mode 100644 index 0000000000..4ecacc975b --- /dev/null +++ b/src/library/scala/math/Numeric.scala @@ -0,0 +1,188 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +/** + * @since 2.8 + */ +object Numeric { + trait BigIntIsIntegral extends Integral[BigInt] { + def plus(x: BigInt, y: BigInt): BigInt = x + y + def minus(x: BigInt, y: BigInt): BigInt = x - y + def times(x: BigInt, y: BigInt): BigInt = x * y + def quot(x: BigInt, y: BigInt): BigInt = x / y + def rem(x: BigInt, y: BigInt): BigInt = x % y + def negate(x: BigInt): BigInt = -x + def fromInt(x: Int): BigInt = BigInt(x) + def toInt(x: BigInt): Int = x.intValue + def toLong(x: BigInt): Long = x.longValue + def toFloat(x: BigInt): Float = x.longValue.toFloat + def toDouble(x: BigInt): Double = x.longValue.toDouble + } + implicit object BigIntIsIntegral extends BigIntIsIntegral with Ordering.BigIntOrdering + + trait IntIsIntegral extends Integral[Int] { + def plus(x: Int, y: Int): Int = x + y + def minus(x: Int, y: Int): Int = x - y + def times(x: Int, y: Int): Int = x * y + def quot(x: Int, y: Int): Int = x / y + def rem(x: Int, y: Int): Int = x % y + def negate(x: Int): Int = -x + def fromInt(x: Int): Int = x + def toInt(x: Int): Int = x + def toLong(x: Int): Long = x + def toFloat(x: Int): Float = x + def toDouble(x: Int): Double = x + } + implicit object IntIsIntegral extends IntIsIntegral with Ordering.IntOrdering + + trait ShortIsIntegral extends Integral[Short] { + def plus(x: Short, y: Short): Short = (x + y).toShort + def minus(x: Short, y: Short): Short = (x - y).toShort + def times(x: Short, y: Short): Short = (x * y).toShort + def quot(x: Short, y: Short): Short = (x / y).toShort + def rem(x: Short, y: Short): Short = (x % y).toShort + def negate(x: Short): Short = (-x).toShort + def fromInt(x: Int): Short = x.toShort + def toInt(x: Short): Int = x.toInt + def toLong(x: Short): Long = x.toLong + def toFloat(x: Short): Float = x.toFloat + def toDouble(x: Short): Double = x.toDouble + } + implicit object ShortIsIntegral extends ShortIsIntegral with Ordering.ShortOrdering + + trait ByteIsIntegral extends 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 + def quot(x: Byte, y: Byte): Byte = (x / y).toByte + def rem(x: Byte, y: Byte): Byte = (x % y).toByte + def negate(x: Byte): Byte = (-x).toByte + def fromInt(x: Int): Byte = x.toByte + def toInt(x: Byte): Int = x.toInt + def toLong(x: Byte): Long = x.toLong + def toFloat(x: Byte): Float = x.toFloat + def toDouble(x: Byte): Double = x.toDouble + } + implicit object ByteIsIntegral extends ByteIsIntegral with Ordering.ByteOrdering + + trait LongIsIntegral extends Integral[Long] { + def plus(x: Long, y: Long): Long = x + y + def minus(x: Long, y: Long): Long = x - y + def times(x: Long, y: Long): Long = x * y + def quot(x: Long, y: Long): Long = x / y + def rem(x: Long, y: Long): Long = x % y + def negate(x: Long): Long = -x + def fromInt(x: Int): Long = x + def toInt(x: Long): Int = x.toInt + def toLong(x: Long): Long = x + def toFloat(x: Long): Float = x + def toDouble(x: Long): Double = x + } + implicit object LongIsIntegral extends LongIsIntegral with Ordering.LongOrdering + + trait FloatIsFractional extends Fractional[Float] { + def plus(x: Float, y: Float): Float = x + y + def minus(x: Float, y: Float): Float = x - y + def times(x: Float, y: Float): Float = x * y + def div(x: Float, y: Float): Float = x / y + def negate(x: Float): Float = -x + def fromInt(x: Int): Float = x + def toInt(x: Float): Int = x.toInt + def toLong(x: Float): Long = x.toLong + def toFloat(x: Float): Float = x + def toDouble(x: Float): Double = x + } + implicit object FloatIsFractional extends FloatIsFractional with Ordering.FloatOrdering + + trait DoubleIsConflicted extends Numeric[Double] { + def plus(x: Double, y: Double): Double = x + y + def minus(x: Double, y: Double): Double = x - y + def times(x: Double, y: Double): Double = x * y + def negate(x: Double): Double = -x + def fromInt(x: Int): Double = x + def toInt(x: Double): Int = x.toInt + def toLong(x: Double): Long = x.toLong + def toFloat(x: Double): Float = x.toFloat + def toDouble(x: Double): Double = x + } + trait DoubleIsFractional extends DoubleIsConflicted with Fractional[Double] { + def div(x: Double, y: Double): Double = x / y + } + trait DoubleAsIfIntegral extends DoubleIsConflicted with Integral[Double] { + def quot(x: Double, y: Double): Double = (BigDecimal(x) / BigDecimal(y)).doubleValue + def rem(x: Double, y: Double): Double = (BigDecimal(x) remainder BigDecimal(y)).doubleValue + } + + trait BigDecimalIsConflicted extends Numeric[BigDecimal] { + def plus(x: BigDecimal, y: BigDecimal): BigDecimal = x + y + def minus(x: BigDecimal, y: BigDecimal): BigDecimal = x - y + def times(x: BigDecimal, y: BigDecimal): BigDecimal = x * y + def negate(x: BigDecimal): BigDecimal = -x + def fromInt(x: Int): BigDecimal = BigDecimal(x) + def toInt(x: BigDecimal): Int = x.intValue + def toLong(x: BigDecimal): Long = x.longValue + def toFloat(x: BigDecimal): Float = x.floatValue + def toDouble(x: BigDecimal): Double = x.doubleValue + } + + trait BigDecimalIsFractional extends BigDecimalIsConflicted with Fractional[BigDecimal] { + def div(x: BigDecimal, y: BigDecimal): BigDecimal = x / y + } + trait BigDecimalAsIfIntegral extends BigDecimalIsConflicted with Integral[BigDecimal] { + def quot(x: BigDecimal, y: BigDecimal): BigDecimal = x / y + def rem(x: BigDecimal, y: BigDecimal): BigDecimal = x remainder y + } + + // 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 DoubleIsFractional extends DoubleIsFractional with Ordering.DoubleOrdering + object DoubleAsIfIntegral extends DoubleAsIfIntegral with Ordering.DoubleOrdering +} + +trait Numeric[T] extends Ordering[T] { + def plus(x: T, y: T): T + def minus(x: T, y: T): T + def times(x: T, y: T): T + def negate(x: T): T + def fromInt(x: Int): T + def toInt(x: T): Int + def toLong(x: T): Long + def toFloat(x: T): Float + def toDouble(x: T): Double + + def zero = fromInt(0) + def one = fromInt(1) + + def abs(x: T): T = if (lt(x, zero)) negate(x) else x + def signum(x: T): Int = + if (lt(x, zero)) -1 + else if (gt(x, zero)) 1 + else 0 + + class Ops(lhs: T) { + def +(rhs: T) = plus(lhs, rhs) + def -(rhs: T) = minus(lhs, rhs) + def *(rhs: T) = times(lhs, rhs) + def unary_-() = negate(lhs) + def abs(): T = Numeric.this.abs(lhs) + def signum(): Int = Numeric.this.signum(lhs) + def toInt(): Int = Numeric.this.toInt(lhs) + def toLong(): Long = Numeric.this.toLong(lhs) + def toFloat(): Float = Numeric.this.toFloat(lhs) + def toDouble(): Double = Numeric.this.toDouble(lhs) + } + implicit def mkNumericOps(lhs: T): Ops = new Ops(lhs) +} diff --git a/src/library/scala/math/Ordered.scala b/src/library/scala/math/Ordered.scala new file mode 100644 index 0000000000..bd84b1a6a2 --- /dev/null +++ b/src/library/scala/math/Ordered.scala @@ -0,0 +1,57 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +/** A trait for totally ordered data. + * + * Note that since version 2006-07-24 this trait is no longer covariant in a. + * + * It is important that the equals method for an instance of + * Ordered[A] be consistent with the compare method. However, + * due to limitations inherent in the type erasure semantics, + * there is no reasonable way to provide a default implementation + * of equality for instances of Ordered[A]. Therefore, if you need + * to be able to use equality on an instance of Ordered[A] you must + * provide it yourself either when inheiriting or instantiating. + * + * It is important that the hashCode method for an instance of + * Ordered[A] be consistent with the compare method. However, + * it is not possible to provide a sensible default implementation. + * Therefore, if you need to be able compute the hash of an + * instance of Ordered[A] you must provide it yourself either when + * inheiriting or instantiating. + * + * @author Martin Odersky + * @version 1.1, 2006-07-24 + */ +trait Ordered[A] extends java.lang.Comparable[A] { + + /** Result of comparing this with operand that. + * returns x where + * x < 0 iff this < that + * x == 0 iff this == that + * x > 0 iff this > that + */ + def compare(that: A): Int + + def < (that: A): Boolean = (this compare that) < 0 + def > (that: A): Boolean = (this compare that) > 0 + def <= (that: A): Boolean = (this compare that) <= 0 + def >= (that: A): Boolean = (this compare that) >= 0 + def compareTo(that: A): Int = compare(that) +} + +object Ordered { + /** Lens from Ordering[T] to Ordered[T] */ + implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = + new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) } +} diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala new file mode 100644 index 0000000000..30e13d9f0e --- /dev/null +++ b/src/library/scala/math/Ordering.scala @@ -0,0 +1,370 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +import java.util.Comparator + +/** A trait for representing total orderings. It is important to + * distinguish between a type that has a total order and a representation + * of total ordering on some type. This trait is for representing the + * latter. + * + * A total ordering + * is a binary relation on a type T that is also an equivalence relation + * and partial ordering on values of type T. This relation is exposed as + * the compare method of the Ordering trait. + * This relation must be: + * + * + * @author Geoffrey Washburn + * @version 0.9.5, 2008-04-15 + * @since 2.7 + */ +@serializable +trait Ordering[T] extends Comparator[T] with PartialOrdering[T] { + outer => + + /** An Ordering is defined at all x and y. */ + def tryCompare(x: T, y: T) = Some(compare(x, y)) + + /** Returns a negative integer iff x comes before + * y in the ordering, returns 0 iff x + * is the same in the ordering as y, and returns a + * positive number iff x comes after + * y in the ordering. + */ + def compare(x: T, y: T): Int + + /** Returns true iff x comes before + * y in the ordering. + */ + override def lteq(x: T, y: T): Boolean = compare(x, y) <= 0 + + /** Returns true iff y comes before + * x in the ordering. + */ + override def gteq(x: T, y: T): Boolean = compare(x, y) >= 0 + + /** Returns true iff x comes before + * y in the ordering and is not the same as y. + */ + override def lt(x: T, y: T): Boolean = compare(x, y) < 0 + + /** Returns true iff y comes before + * x in the ordering and is not the same as x. + */ + override def gt(x: T, y: T): Boolean = compare(x, y) > 0 + + /** Returns true iff x is equivalent to + * y in the ordering. + */ + override def equiv(x: T, y: T): Boolean = compare(x, y) == 0 + + /** Returns the argument which comes later in the ordering. */ + def max(x: T, y: T): T = if (gteq(x, y)) x else y + + /** Returns the argument which comes earlier in the ordering. */ + def min(x: T, y: T): T = if (lteq(x, y)) x else y + + override def reverse: Ordering[T] = new Ordering[T]{ + override def reverse = outer + def compare(x: T, y: T) = outer.compare(y, x) + } + + /** Given a function U => T, creates Ordering[U]. */ + def on[U](f: U => T): Ordering[U] = new Ordering[U] { + def compare(x: U, y: U) = outer.compare(f(x), f(y)) + } + + class Ops(lhs: T) { + def <(rhs: T) = lt(lhs, rhs) + def <=(rhs: T) = lteq(lhs, rhs) + def >(rhs: T) = gt(lhs, rhs) + def >=(rhs: T) = gteq(lhs, rhs) + def equiv(rhs: T) = Ordering.this.equiv(lhs, rhs) + def max(rhs: T): T = Ordering.this.max(lhs, rhs) + def min(rhs: T): T = Ordering.this.min(lhs, rhs) + } + implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs) +} + +/** This would conflict with all the nice implicit Orderings + * available, but thanks to the magic of prioritized implicits + * via subclassing we can make Ordered[A] => Ordering[A] only + * turn up if nothing else works. + */ +trait LowPriorityOrderingImplicits { + implicit def ordered[A <: Ordered[A]]: Ordering[A] = new Ordering[A] { + def compare(x: A, y: A) = x.compare(y) + } +} + +object Ordering extends LowPriorityOrderingImplicits { + + def apply[T](implicit ord : Ordering[T]) = ord + + def fromLessThan[T](cmp: (T, T) => Boolean): Ordering[T] = new Ordering[T] { + def compare(x: T, y: T) = if (cmp(x, y)) -1 else if (cmp(y, x)) 1 else 0 + } + + trait UnitOrdering extends Ordering[Unit] { + def compare(x: Unit, y: Unit) = 0 + } + implicit object Unit extends UnitOrdering + + trait BooleanOrdering extends Ordering[Boolean] { + def compare(x: Boolean, y: Boolean) = (x, y) match { + case (false, true) => -1 + case (true, false) => 1 + case _ => 0 + } + } + implicit object Boolean extends BooleanOrdering + + trait ByteOrdering extends Ordering[Byte] { + def compare(x: Byte, y: Byte) = x.toInt - y.toInt + } + implicit object Byte extends ByteOrdering + + trait CharOrdering extends Ordering[Char] { + def compare(x: Char, y: Char) = x.toInt - y.toInt + } + implicit object Char extends CharOrdering + + trait ShortOrdering extends Ordering[Short] { + def compare(x: Short, y: Short) = x.toInt - y.toInt + } + implicit object Short extends ShortOrdering + + trait IntOrdering extends Ordering[Int] { + def compare(x: Int, y: Int) = + if (x < y) -1 + else if (x == y) 0 + else 1 + } + implicit object Int extends IntOrdering + + trait LongOrdering extends Ordering[Long] { + def compare(x: Long, y: Long) = + if (x < y) -1 + else if (x == y) 0 + else 1 + } + implicit object Long extends LongOrdering + + trait FloatOrdering extends Ordering[Float] { + def compare(x: Float, y: Float) = java.lang.Float.compare(x, y) + } + implicit object Float extends FloatOrdering + + trait DoubleOrdering extends Ordering[Double] { + def compare(x: Double, y: Double) = java.lang.Double.compare(x, y) + } + implicit object Double extends DoubleOrdering + + trait BigIntOrdering extends Ordering[BigInt] { + def compare(x: BigInt, y: BigInt) = x.compare(y) + } + implicit object BigInt extends BigIntOrdering + + trait BigDecimalOrdering extends Ordering[BigDecimal] { + def compare(x: BigDecimal, y: BigDecimal) = x.compare(y) + } + implicit object BigDecimal extends BigDecimalOrdering + + trait StringOrdering extends Ordering[String] { + def compare(x: String, y: String) = x.compareTo(y) + } + implicit object String extends StringOrdering + + implicit def Option[T](implicit ord: Ordering[T]) : Ordering[Option[T]] = + new Ordering[Option[T]] { + def compare(x : Option[T], y : Option[T]) = (x, y) match { + case (None, None) => 0 + case (None, _) => -1 + case (_, None) => 1 + case (Some(x), Some(y)) => ord.compare(x, y) + } + } + + implicit def Iterable[T](implicit ord: Ordering[T]): Ordering[Iterable[T]] = + new Ordering[Iterable[T]] { + def compare(x: Iterable[T], y: Iterable[T]): Int = { + val xe = x.iterator + val ye = y.iterator + + while (xe.hasNext && ye.hasNext) { + val res = ord.compare(xe.next, ye.next) + if (res != 0) return res + } + + Boolean.compare(xe.hasNext, ye.hasNext) + } + } + + implicit def Tuple2[T1, T2](implicit ord1: Ordering[T1], ord2: Ordering[T2]): Ordering[(T1, T2)] = + new Ordering[(T1, T2)]{ + def compare(x: (T1, T2), y: (T1, T2)): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + 0 + } + } + + implicit def Tuple3[T1, T2, T3](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3]) : Ordering[(T1, T2, T3)] = + new Ordering[(T1, T2, T3)]{ + def compare(x: (T1, T2, T3), y: (T1, T2, T3)): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + val compare3 = ord3.compare(x._3, y._3) + if (compare3 != 0) return compare3 + 0 + } + } + + implicit def Tuple4[T1, T2, T3, T4](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4]) : Ordering[(T1, T2, T3, T4)] = + new Ordering[(T1, T2, T3, T4)]{ + def compare(x: (T1, T2, T3, T4), y: (T1, T2, T3, T4)): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + val compare3 = ord3.compare(x._3, y._3) + if (compare3 != 0) return compare3 + val compare4 = ord4.compare(x._4, y._4) + if (compare4 != 0) return compare4 + 0 + } + } + + implicit def Tuple5[T1, T2, T3, T4, T5](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5]): Ordering[(T1, T2, T3, T4, T5)] = + new Ordering[(T1, T2, T3, T4, T5)]{ + def compare(x: (T1, T2, T3, T4, T5), y: Tuple5[T1, T2, T3, T4, T5]): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + val compare3 = ord3.compare(x._3, y._3) + if (compare3 != 0) return compare3 + val compare4 = ord4.compare(x._4, y._4) + if (compare4 != 0) return compare4 + val compare5 = ord5.compare(x._5, y._5) + if (compare5 != 0) return compare5 + 0 + } + } + + implicit def Tuple6[T1, T2, T3, T4, T5, T6](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6]): Ordering[(T1, T2, T3, T4, T5, T6)] = + new Ordering[(T1, T2, T3, T4, T5, T6)]{ + def compare(x: (T1, T2, T3, T4, T5, T6), y: (T1, T2, T3, T4, T5, T6)): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + val compare3 = ord3.compare(x._3, y._3) + if (compare3 != 0) return compare3 + val compare4 = ord4.compare(x._4, y._4) + if (compare4 != 0) return compare4 + val compare5 = ord5.compare(x._5, y._5) + if (compare5 != 0) return compare5 + val compare6 = ord6.compare(x._6, y._6) + if (compare6 != 0) return compare6 + 0 + } + } + + implicit def Tuple7[T1, T2, T3, T4, T5, T6, T7](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6], ord7: Ordering[T7]): Ordering[(T1, T2, T3, T4, T5, T6, T7)] = + new Ordering[(T1, T2, T3, T4, T5, T6, T7)]{ + def compare(x: (T1, T2, T3, T4, T5, T6, T7), y: (T1, T2, T3, T4, T5, T6, T7)): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + val compare3 = ord3.compare(x._3, y._3) + if (compare3 != 0) return compare3 + val compare4 = ord4.compare(x._4, y._4) + if (compare4 != 0) return compare4 + val compare5 = ord5.compare(x._5, y._5) + if (compare5 != 0) return compare5 + val compare6 = ord6.compare(x._6, y._6) + if (compare6 != 0) return compare6 + val compare7 = ord7.compare(x._7, y._7) + if (compare7 != 0) return compare7 + 0 + } + } + + implicit def Tuple8[T1, T2, T3, T4, T5, T6, T7, T8](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6], ord7: Ordering[T7], ord8: Ordering[T8]): Ordering[(T1, T2, T3, T4, T5, T6, T7, T8)] = + new Ordering[(T1, T2, T3, T4, T5, T6, T7, T8)]{ + def compare(x: (T1, T2, T3, T4, T5, T6, T7, T8), y: (T1, T2, T3, T4, T5, T6, T7, T8)): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + val compare3 = ord3.compare(x._3, y._3) + if (compare3 != 0) return compare3 + val compare4 = ord4.compare(x._4, y._4) + if (compare4 != 0) return compare4 + val compare5 = ord5.compare(x._5, y._5) + if (compare5 != 0) return compare5 + val compare6 = ord6.compare(x._6, y._6) + if (compare6 != 0) return compare6 + val compare7 = ord7.compare(x._7, y._7) + if (compare7 != 0) return compare7 + val compare8 = ord8.compare(x._8, y._8) + if (compare8 != 0) return compare8 + 0 + } + } + + implicit def Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](implicit ord1: Ordering[T1], ord2: Ordering[T2], ord3: Ordering[T3], ord4: Ordering[T4], ord5: Ordering[T5], ord6: Ordering[T6], ord7: Ordering[T7], ord8 : Ordering[T8], ord9: Ordering[T9]): Ordering[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] = + new Ordering[(T1, T2, T3, T4, T5, T6, T7, T8, T9)]{ + def compare(x: (T1, T2, T3, T4, T5, T6, T7, T8, T9), y: (T1, T2, T3, T4, T5, T6, T7, T8, T9)): Int = { + val compare1 = ord1.compare(x._1, y._1) + if (compare1 != 0) return compare1 + val compare2 = ord2.compare(x._2, y._2) + if (compare2 != 0) return compare2 + val compare3 = ord3.compare(x._3, y._3) + if (compare3 != 0) return compare3 + val compare4 = ord4.compare(x._4, y._4) + if (compare4 != 0) return compare4 + val compare5 = ord5.compare(x._5, y._5) + if (compare5 != 0) return compare5 + val compare6 = ord6.compare(x._6, y._6) + if (compare6 != 0) return compare6 + val compare7 = ord7.compare(x._7, y._7) + if (compare7 != 0) return compare7 + val compare8 = ord8.compare(x._8, y._8) + if (compare8 != 0) return compare8 + val compare9 = ord9.compare(x._9, y._9) + if (compare9 != 0) return compare9 + 0 + } + } + +} diff --git a/src/library/scala/math/PartialOrdering.scala b/src/library/scala/math/PartialOrdering.scala new file mode 100644 index 0000000000..0f3f667cd5 --- /dev/null +++ b/src/library/scala/math/PartialOrdering.scala @@ -0,0 +1,86 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +/**

+ * A trait for representing partial orderings. It is important to + * distinguish between a type that has a partial order and a representation + * of partial ordering on some type. This trait is for representing the + * latter. + *

+ *

+ * A partial ordering + * is a binary relation on a type T that is also an equivalence + * relation on values of type T. This relation is exposed as + * the lteq method of the PartialOrdering trait. + * This relation must be: + *

+ * + * + * @author Geoffrey Washburn + * @version 1.0, 2008-04-0-3 + * @since 2.7 + */ + +trait PartialOrdering[T] extends Equiv[T] { + outer => + + /** Result of comparing x with operand y. + * Returns None if operands are not comparable. + * If operands are comparable, returns Some(r) where + * r < 0 iff x < y + * r == 0 iff x == y + * r > 0 iff x > y + */ + def tryCompare(x: T, y: T): Option[Int] + + /** Returns true iff x comes before + * y in the ordering. + */ + def lteq(x: T, y: T): Boolean + + /** Returns true iff y comes before + * x in the ordering. + */ + def gteq(x: T, y: T): Boolean = lteq(y, x) + + /** Returns true iff x comes before + * y in the ordering and is not the same as y. + */ + def lt(x: T, y: T): Boolean = lteq(x, y) && !equiv(x, y) + + /** Returns true iff y comes before + * x in the ordering and is not the same as x. + */ + def gt(x: T, y: T): Boolean = gteq(x, y) && !equiv(x, y) + + /** Returns true iff x is equivalent to + * y in the ordering. + */ + def equiv(x: T, y: T): Boolean = lteq(x,y) && lteq(y,x) + + def reverse : PartialOrdering[T] = new PartialOrdering[T] { + override def reverse = outer + def lteq(x: T, y: T) = outer.lteq(y, x) + def tryCompare(x: T, y: T) = outer.tryCompare(y, x) + } +} diff --git a/src/library/scala/math/PartiallyOrdered.scala b/src/library/scala/math/PartiallyOrdered.scala new file mode 100644 index 0000000000..a09d8326f4 --- /dev/null +++ b/src/library/scala/math/PartiallyOrdered.scala @@ -0,0 +1,50 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.math + +/** A class for partially ordered data. + * + * @author Martin Odersky + * @version 1.0, 23/04/2004 + */ +trait PartiallyOrdered[+A] { + + /** Result of comparing this with operand that. + * Returns None if operands are not comparable. + * If operands are comparable, returns Some(x) where + * x < 0 iff this < that + * x == 0 iff this == that + * x > 0 iff this > that + */ + def tryCompareTo [B >: A <% PartiallyOrdered[B]](that: B): Option[Int] + + def < [B >: A <% PartiallyOrdered[B]](that: B): Boolean = + (this tryCompareTo that) match { + case Some(x) if x < 0 => true + case _ => false + } + def > [B >: A <% PartiallyOrdered[B]](that: B): Boolean = + (this tryCompareTo that) match { + case Some(x) if x > 0 => true + case _ => false + } + def <= [B >: A <% PartiallyOrdered[B]](that: B): Boolean = + (this tryCompareTo that) match { + case Some(x) if x <= 0 => true + case _ => false + } + def >= [B >: A <% PartiallyOrdered[B]](that: B): Boolean = + (this tryCompareTo that) match { + case Some(x) if x >= 0 => true + case _ => false + } +} diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 34ba3c1ff2..e45e5cebe7 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -49,6 +49,30 @@ package object scala { type Range = scala.collection.immutable.Range val Range = scala.collection.immutable.Range + // Numeric types which were moved into scala.math.* + + type BigDecimal = scala.math.BigDecimal + val BigDecimal = scala.math.BigDecimal + + type BigInt = scala.math.BigInt + val BigInt = scala.math.BigInt + + type Equiv[T] = scala.math.Equiv[T] + type Fractional[T] = scala.math.Fractional[T] + type Integral[T] = scala.math.Integral[T] + + type Numeric[T] = scala.math.Numeric[T] + val Numeric = scala.math.Numeric + + type Ordered[T] = scala.math.Ordered[T] + val Ordered = scala.math.Ordered + + type Ordering[T] = scala.math.Ordering[T] + val Ordering = scala.math.Ordering + + type PartialOrdering[T] = scala.math.PartialOrdering[T] + type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T] + @deprecated("use Iterable instead") type Collection[+A] = Iterable[A] @deprecated("use Iterable instead") val Collection = Iterable -- cgit v1.2.3