Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions library/src/scala/math/BigDecimal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ object BigDecimal {
*
* @param d the `Double` value to convert to a `BigDecimal`
* @param mc the precision and rounding mode for the conversion
* @return a `BigDecimal` representing the decimal text form of `d`, rounded per `mc`
*/
def decimal(d: Double, mc: MathContext): BigDecimal =
new BigDecimal(new BigDec(java.lang.Double.toString(d), mc), mc)

/** Constructs a `BigDecimal` using the decimal text representation of `Double` value `d`.
*
* @param d the `Double` value to convert to a `BigDecimal`
* @return a `BigDecimal` representing the decimal text form of `d`, using the default `MathContext`
*/
def decimal(d: Double): BigDecimal = decimal(d, defaultMathContext)

Expand All @@ -68,6 +70,7 @@ object BigDecimal {
*
* @param f the `Float` value to convert to a `BigDecimal`
* @param mc the precision and rounding mode for the conversion
* @return a `BigDecimal` representing the decimal text form of `f`, rounded per `mc`
*/
def decimal(f: Float, mc: MathContext): BigDecimal =
new BigDecimal(new BigDec(java.lang.Float.toString(f), mc), mc)
Expand All @@ -77,6 +80,7 @@ object BigDecimal {
* `0.1 != 0.1f`.
*
* @param f the `Float` value to convert to a `BigDecimal`
* @return a `BigDecimal` representing the decimal text form of `f`, using the default `MathContext`
*/
def decimal(f: Float): BigDecimal = decimal(f, defaultMathContext)

Expand All @@ -85,20 +89,23 @@ object BigDecimal {
*
* @param l the `Long` value to convert to a `BigDecimal`
* @param mc the precision and rounding mode for the conversion
* @return a `BigDecimal` whose value equals `l`, rounded per `mc`
*/
def decimal(l: Long, mc: MathContext): BigDecimal = apply(l, mc)

// This exists solely to avoid conversion from Int/Long to Float, screwing everything up.
/** Constructs a `BigDecimal` from a `Long`. This is identical to `BigDecimal(l)`.
*
* @param l the `Long` value to convert to a `BigDecimal`
* @return a `BigDecimal` whose value equals `l`, using the default `MathContext`
*/
def decimal(l: Long): BigDecimal = apply(l)

/** Constructs a `BigDecimal` using a `java.math.BigDecimal`, rounding if necessary.
*
* @param bd the `java.math.BigDecimal` to convert
* @param mc the precision and rounding mode for the conversion
* @return a `BigDecimal` wrapping `bd` rounded per `mc`
*/
def decimal(bd: BigDec, mc: MathContext): BigDecimal = new BigDecimal(bd.round(mc), mc)

Expand All @@ -110,6 +117,7 @@ object BigDecimal {
*
* @param d the `Double` value whose binary fraction is expanded
* @param mc the precision and rounding mode for the conversion
* @return a `BigDecimal` holding the binary expansion of `d`, rounded per `mc`
*/
def binary(d: Double, mc: MathContext): BigDecimal = new BigDecimal(new BigDec(d, mc), mc)

Expand All @@ -118,6 +126,7 @@ object BigDecimal {
* Note: this also works correctly on converted `Float`s.
*
* @param d the `Double` value whose binary fraction is expanded
* @return a `BigDecimal` holding the binary expansion of `d`, using the default `MathContext`
*/
def binary(d: Double): BigDecimal = binary(d, defaultMathContext)

Expand All @@ -126,6 +135,7 @@ object BigDecimal {
* the `java.math.BigDecimal` exactly, whichever is greater.
*
* @param repr the `java.math.BigDecimal` to represent exactly
* @return a `BigDecimal` exactly equal to `repr` with precision sufficient to preserve it
*/
def exact(repr: BigDec): BigDecimal = {
val mc =
Expand All @@ -139,12 +149,14 @@ object BigDecimal {
* necessary. Note: this works correctly on converted `Float`s also.
*
* @param d the `Double` value whose binary fraction is fully expanded
* @return a `BigDecimal` exactly equal to the full decimal expansion of `d`'s binary fraction
*/
def exact(d: Double): BigDecimal = exact(new BigDec(d))

/** Constructs a `BigDecimal` that exactly represents a `BigInt`.
*
* @param bi the `BigInt` value to represent exactly
* @return a `BigDecimal` whose value exactly equals `bi`
*/
def exact(bi: BigInt): BigDecimal = exact(new BigDec(bi.bigInteger))

Expand All @@ -153,20 +165,23 @@ object BigDecimal {
* represent a `Long`; this is equivalent to `apply`, `valueOf`, etc..
*
* @param l the `Long` value to represent exactly
* @return a `BigDecimal` exactly equal to `l`
*/
def exact(l: Long): BigDecimal = apply(l)

/** Constructs a `BigDecimal` that exactly represents the number
* specified in a `String`.
*
* @param s the string representation of the number
* @return a `BigDecimal` exactly equal to the value parsed from `s`
*/
def exact(s: String): BigDecimal = exact(new BigDec(s))

/** Constructs a `BigDecimal` that exactly represents the number
* specified in base 10 in a character array.
*
* @param cs the character array containing the decimal representation
* @return a `BigDecimal` exactly equal to the value parsed from `cs`
*/
def exact(cs: Array[Char]): BigDecimal = exact(new BigDec(cs))

Expand Down Expand Up @@ -276,6 +291,7 @@ object BigDecimal {
* into a `BigDecimal`.
*
* @param x the character array containing the decimal representation
* @return a `BigDecimal` exactly equal to the value parsed from `x`
*/
def apply(x: Array[Char]): BigDecimal = exact(x)

Expand All @@ -284,6 +300,7 @@ object BigDecimal {
*
* @param x the character array containing the decimal representation
* @param mc the precision and rounding mode for creation of this value and future operations on it
* @return the constructed `BigDecimal`
*/
def apply(x: Array[Char], mc: MathContext): BigDecimal =
new BigDecimal(new BigDec(x, mc), mc)
Expand All @@ -292,6 +309,7 @@ object BigDecimal {
* into a `BigDecimal`.
*
* @param x the string representation of the decimal value
* @return a `BigDecimal` exactly equal to the value parsed from `x`
*/
def apply(x: String): BigDecimal = exact(x)

Expand All @@ -300,6 +318,7 @@ object BigDecimal {
*
* @param x the string representation of the decimal value
* @param mc the precision and rounding mode for creation of this value and future operations on it
* @return the constructed `BigDecimal`
*/
def apply(x: String, mc: MathContext): BigDecimal =
new BigDecimal(new BigDec(x, mc), mc)
Expand Down Expand Up @@ -346,24 +365,28 @@ object BigDecimal {
/** Constructs a `BigDecimal` from a `java.math.BigDecimal`.
*
* @param bd the `java.math.BigDecimal` to convert
* @return a `BigDecimal` wrapping `bd` with the default `MathContext`
*/
def apply(bd: BigDec): BigDecimal = new BigDecimal(bd, defaultMathContext)

/** Implicit conversion from `Int` to `BigDecimal`.
*
* @param i the `Int` value to convert
* @return a `BigDecimal` whose value equals `i`
*/
implicit def int2bigDecimal(i: Int): BigDecimal = apply(i)

/** Implicit conversion from `Long` to `BigDecimal`.
*
* @param l the `Long` value to convert
* @return a `BigDecimal` whose value equals `l`
*/
implicit def long2bigDecimal(l: Long): BigDecimal = apply(l)

/** Implicit conversion from `Double` to `BigDecimal`.
*
* @param d the `Double` value to convert
* @return a `BigDecimal` representing the decimal text form of `d`
*/
implicit def double2bigDecimal(d: Double): BigDecimal = decimal(d)

Expand All @@ -375,6 +398,7 @@ object BigDecimal {
/** Implicit conversion from `java.math.BigDecimal` to `scala.BigDecimal`.
*
* @param x the `java.math.BigDecimal` to convert
* @return a `scala.BigDecimal` wrapping `x`, or `null` if `x` is `null`
*/
implicit def javaBigDecimal2bigDecimal(x: BigDec): BigDecimal = mapNull(x, apply(x))
}
Expand Down Expand Up @@ -474,6 +498,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
* disagree, `BigDecimal` will agree with the `Double` value
*
* @param that the value to compare with this `BigDecimal`
* @return `true` if `that` is numerically equal to this `BigDecimal` under the comparison rules described above, `false` otherwise
*/
override def equals (that: Any): Boolean = that match {
case that: BigDecimal => this equals that
Expand Down Expand Up @@ -548,12 +573,14 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
/** Compares this BigDecimal with the specified BigDecimal for equality.
*
* @param that the `BigDecimal` to compare with
* @return `true` if this and `that` represent the same numeric value, `false` otherwise
*/
def equals (that: BigDecimal): Boolean = compare(that) == 0

/** Compares this BigDecimal with the specified BigDecimal
*
* @param that the `BigDecimal` to compare with
* @return a negative number, zero, or a positive number if this is less than, equal to, or greater than `that`
*/
def compare (that: BigDecimal): Int = this.bigDecimal.compareTo(that.bigDecimal)

Expand Down Expand Up @@ -594,13 +621,15 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
/** Divide to Integral value.
*
* @param that the `BigDecimal` divisor
* @return the integer part of `this / that` as a `BigDecimal`
*/
def quot (that: BigDecimal): BigDecimal =
new BigDecimal(this.bigDecimal.divideToIntegralValue(that.bigDecimal, mc), mc)

/** Returns the minimum of this and that, or this if the two are equal
*
* @param that the `BigDecimal` to compare with
* @return the smaller of `this` and `that`, or `this` if they are equal
*/
def min (that: BigDecimal): BigDecimal = (this compare that) match {
case x if x <= 0 => this
Expand All @@ -610,6 +639,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
/** Returns the maximum of this and that, or this if the two are equal
*
* @param that the `BigDecimal` to compare with
* @return the larger of `this` and `that`, or `this` if they are equal
*/
def max (that: BigDecimal): BigDecimal = (this compare that) match {
case x if x >= 0 => this
Expand All @@ -619,6 +649,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
/** Remainder after dividing this by that.
*
* @param that the `BigDecimal` divisor
* @return the remainder of `this / that` as a `BigDecimal`
*/
def remainder (that: BigDecimal): BigDecimal = new BigDecimal(this.bigDecimal.remainder(that.bigDecimal, mc), mc)

Expand All @@ -631,6 +662,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
/** Returns a BigDecimal whose value is this ** n.
*
* @param n the exponent to raise this `BigDecimal` to
* @return a `BigDecimal` whose value is `this` raised to the power `n`
*/
def pow (n: Int): BigDecimal = new BigDecimal(this.bigDecimal.pow(n, mc), mc)

Expand Down Expand Up @@ -661,6 +693,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
* preserving its own MathContext for future operations.
*
* @param mc the `MathContext` specifying the precision and rounding mode
* @return a `BigDecimal` rounded per `mc`, retaining this instance's own `MathContext`
*/
def round(mc: MathContext): BigDecimal = {
val r = this.bigDecimal.round(mc)
Expand All @@ -682,13 +715,15 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
/** Returns a new BigDecimal based on the supplied MathContext, rounded as needed.
*
* @param mc the new `MathContext` for precision and rounding
* @return a `BigDecimal` rounded per `mc` and carrying `mc` as its `MathContext`
*/
def apply(mc: MathContext): BigDecimal = new BigDecimal(this.bigDecimal.round(mc), mc)

/** Returns a `BigDecimal` whose scale is the specified value, and whose value is
* numerically equal to this BigDecimal's.
*
* @param scale the scale to set for this `BigDecimal`
* @return a `BigDecimal` numerically equal to this one but with the requested `scale`
*/
def setScale(scale: Int): BigDecimal =
if (this.scale == scale) this
Expand Down Expand Up @@ -797,12 +832,14 @@ extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[
*
* @param end the end value of the range (exclusive)
* @param step the increment between successive values in the range
* @return an exclusive `NumericRange` from `this` to `end` by `step`
*/
def until(end: BigDecimal, step: BigDecimal): NumericRange.Exclusive[BigDecimal] = Range.BigDecimal(this, end, step)

/** Like `until`, but inclusive of the end value.
*
* @param end the end value of the range (inclusive)
* @return the partially constructed inclusive `NumericRange` (supply `step` via `by` to complete it)
*/
def to(end: BigDecimal): Range.Partial[BigDecimal, NumericRange.Inclusive[BigDecimal]] =
new Range.Partial(to(end, _))
Expand Down
Loading
Loading