summaryrefslogtreecommitdiff
path: root/src/library/scala/BigDecimal.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-10 21:48:47 +0000
committerPaul Phillips <paulp@improving.org>2009-06-10 21:48:47 +0000
commita46b8b15010eb523cedd8dd23ff7423ca5c73942 (patch)
treee9194794051db190c18f4011a0466cb0260083d7 /src/library/scala/BigDecimal.scala
parent6d09e964f74093d66fa6041c10661df279cdab41 (diff)
downloadscala-a46b8b15010eb523cedd8dd23ff7423ca5c73942.tar.gz
scala-a46b8b15010eb523cedd8dd23ff7423ca5c73942.tar.bz2
scala-a46b8b15010eb523cedd8dd23ff7423ca5c73942.zip
Trying to bring BigDecimal all the way up to sp...
Trying to bring BigDecimal all the way up to speed with its java counterpart. Added a MathContext val and perform all operations with that MathContext, and an apply method which accepts a math context so you can e.g.: val x = BigDecimal(1.0) x / 3 // ArithmeticException x(DECIMAL32) / 3 // 0.3333333 Also added most of the java BigDecimal methods which for whatever reason weren't exposed by the wrapper. Precision to infinity... and beyond!
Diffstat (limited to 'src/library/scala/BigDecimal.scala')
-rw-r--r--src/library/scala/BigDecimal.scala115
1 files changed, 78 insertions, 37 deletions
diff --git a/src/library/scala/BigDecimal.scala b/src/library/scala/BigDecimal.scala
index a1ae26fc01..54409bfa32 100644
--- a/src/library/scala/BigDecimal.scala
+++ b/src/library/scala/BigDecimal.scala
@@ -11,24 +11,26 @@
package scala
import java.math.{BigDecimal => BigDec}
+import java.math.MathContext
/**
* @author Stephane Micheloud
* @version 1.0
*/
-object BigDecimal {
-
+object BigDecimal
+{
@serializable
- object RoundingMode extends Enumeration {
+ object RoundingMode extends Enumeration(java.math.RoundingMode.values map (_.toString) : _*) {
type RoundingMode = Value
- val ROUND_UP, ROUND_DOWN, ROUND_CEILING, ROUND_FLOOR, ROUND_HALF_UP,
- ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_UNNECESSARY = 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 <code>BigDecimal</code> whose value is equal to that of the
* specified <code>Integer</code> value.
*
@@ -53,6 +55,10 @@ object BigDecimal {
if (minCached <= l && l <= maxCached) apply(l.toInt)
else new BigDecimal(BigDec.valueOf(l))
+ def apply(unscaledVal: Long, scale: Int): BigDecimal =
+ if (scale == 0) apply(unscaledVal)
+ else new BigDecimal(BigDec.valueOf(unscaledVal, scale))
+
/** Constructs a <code>BigDecimal</code> whose value is equal to that of the
* specified double value.
*
@@ -74,6 +80,9 @@ object BigDecimal {
def apply(x: String): BigDecimal =
new BigDecimal(new BigDec(x))
+ def apply(x: String, mc: MathContext): BigDecimal =
+ new BigDecimal(new BigDec(x, mc), mc)
+
/** Constructs a <code>BigDecimal</code> whose value is equal to that of the
* specified <code>BigInt</code> value.
*
@@ -113,10 +122,16 @@ object BigDecimal {
* @version 1.0
*/
@serializable
-class BigDecimal(val bigDecimal: BigDec) extends java.lang.Number {
+class BigDecimal(
+ val bigDecimal: BigDec,
+ val mc: MathContext)
+extends java.lang.Number
+{
+ def this(bigDecimal: BigDec) = this(bigDecimal, BigDecimal.defaultMathContext)
import BigDecimal.RoundingMode._
- // import BigDecimal.RoundingMode.{ RoundingMode, ROUND_UP, ROUND_DOWN, ROUND_CEILING, ROUND_FLOOR,
- // ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_UNNECESSARY }
+
+ /** 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. */
override def hashCode(): Int = this.bigDecimal.hashCode()
@@ -134,76 +149,80 @@ class BigDecimal(val bigDecimal: BigDec) extends java.lang.Number {
/** Compares this BigDecimal with the specified BigDecimal for equality.
*/
- def equals (that: BigDecimal): Boolean =
- this.bigDecimal.compareTo(that.bigDecimal) == 0
+ 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)
+ def compare (that: BigDecimal): Int = this.bigDecimal compareTo that.bigDecimal
/** Less-than-or-equals comparison of BigDecimals
*/
- def <= (that: BigDecimal): Boolean = this.bigDecimal.compareTo(that.bigDecimal) <= 0
+ def <= (that: BigDecimal): Boolean = compare(that) <= 0
/** Greater-than-or-equals comparison of BigDecimals
*/
- def >= (that: BigDecimal): Boolean = this.bigDecimal.compareTo(that.bigDecimal) >= 0
+ def >= (that: BigDecimal): Boolean = compare(that) >= 0
/** Less-than of BigDecimals
*/
- def < (that: BigDecimal): Boolean = this.bigDecimal.compareTo(that.bigDecimal) < 0
+ def < (that: BigDecimal): Boolean = compare(that) < 0
/** Greater-than comparison of BigDecimals
*/
- def > (that: BigDecimal): Boolean = this.bigDecimal.compareTo(that.bigDecimal) > 0
+ def > (that: BigDecimal): Boolean = compare(that) > 0
/** Addition of BigDecimals
*/
- def + (that: BigDecimal): BigDecimal =
- new BigDecimal(this.bigDecimal.add(that.bigDecimal))
+ def + (that: BigDecimal): BigDecimal = this.bigDecimal.add(that.bigDecimal, mc)
/** Subtraction of BigDecimals
*/
- def - (that: BigDecimal): BigDecimal =
- new BigDecimal(this.bigDecimal.subtract(that.bigDecimal))
+ def - (that: BigDecimal): BigDecimal = this.bigDecimal.subtract(that.bigDecimal, mc)
/** Multiplication of BigDecimals
*/
- def * (that: BigDecimal): BigDecimal =
- new BigDecimal(this.bigDecimal.multiply(that.bigDecimal))
+ def * (that: BigDecimal): BigDecimal = this.bigDecimal.multiply(that.bigDecimal, mc)
/** Division of BigDecimals
*/
- def / (that: BigDecimal): BigDecimal =
- new BigDecimal(this.bigDecimal.divide(that.bigDecimal))
+ 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 =
- new BigDecimal(this.bigDecimal.min(that.bigDecimal))
+ def min (that: BigDecimal): BigDecimal = this.bigDecimal min that.bigDecimal
/** Returns the maximum of this and that
*/
- def max (that: BigDecimal): BigDecimal =
- new BigDecimal(this.bigDecimal.max(that.bigDecimal))
+ def max (that: BigDecimal): BigDecimal = this.bigDecimal max that.bigDecimal
/** Remainder after dividing this by that.
*/
- def remainder (that: BigDecimal): BigDecimal =
- new BigDecimal(this.bigDecimal remainder that.bigDecimal)
+ def remainder (that: BigDecimal): BigDecimal = this.bigDecimal.remainder(that.bigDecimal, mc)
/** Returns a BigDecimal whose value is this ** n.
*/
- def pow (n: Int): BigDecimal =
- new BigDecimal(this.bigDecimal pow 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 = new BigDecimal(this.bigDecimal.negate())
+ def unary_- : BigDecimal = this.bigDecimal.negate(mc)
/** Returns the absolute value of this BigDecimal
*/
- def abs: BigDecimal = new BigDecimal(this.bigDecimal.abs())
+ def abs: BigDecimal = this.bigDecimal abs mc
/** Returns the sign of this BigDecimal, i.e.
* -1 if it is less than 0,
@@ -212,18 +231,33 @@ class BigDecimal(val bigDecimal: BigDec) extends java.lang.Number {
*/
def signum: Int = this.bigDecimal.signum()
+ /** Returns the precision of this <code>BigDecimal</code>.
+ */
+ 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 <code>BigDecimal</code>.
*/
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 <code>BigDecimal</code> whose scale is the specified value, and whose value is
* numerically equal to this BigDecimal's.
*/
- def setScale(scale: Int): BigDecimal =
- new BigDecimal(this.bigDecimal setScale scale)
+ def setScale(scale: Int): BigDecimal = this.bigDecimal setScale scale
def setScale(scale: Int, mode: RoundingMode): BigDecimal =
- new BigDecimal(this.bigDecimal.setScale(scale, mode.id))
+ this.bigDecimal.setScale(scale, mode.id)
/** Converts this BigDecimal to a <tt>byte</tt>.
* If the BigDecimal is too big to fit in a byte, only the low-order 8 bits are returned.
@@ -276,13 +310,20 @@ class BigDecimal(val bigDecimal: BigDec) extends java.lang.Number {
*/
def doubleValue = this.bigDecimal.doubleValue
+ /** This BigDecimal as an exact value.
+ */
+ def byteValueExact: Byte = bigDecimal.byteValueExact
+ def shortValueExact: Short = bigDecimal.shortValueExact
+ def intValueExact: Int = bigDecimal.intValueExact
+ def longValueExact: Long = bigDecimal.longValueExact
+
/** See <code>Iterator.range</code>. */
def until(end: BigDecimal, step: BigDecimal) = Range.BigDecimal(this, end, step)
/** like <code>until</code>, but includes the last index */
def to(end: BigDecimal, step: BigDecimal) = Range.BigDecimal.inclusive(this, end, step)
- /** Converts this <code>BigDecimal</code> to a BigInteger.
+ /** Converts this <code>BigDecimal</code> to a scala.BigInt.
*/
def toBigInt(): BigInt = new BigInt(this.bigDecimal.toBigInteger())