Hyperlinkv0.8.0-beta.28

BigDecimal

BigDecimal.roundconsteffect/BigDecimal.ts:1750
(options: { scale?: number; mode?: RoundingMode }): (
  self: BigDecimal
) => BigDecimal
(
  n: BigDecimal,
  options?: { scale?: number; mode?: RoundingMode }
): BigDecimal

Computes a rounded BigDecimal at the given scale with the specified rounding mode.

When to use

Use to round a decimal at a requested scale with an explicit rounding mode.

Example (Rounding decimals)

import { BigDecimal } from "effect"
import * as assert from "node:assert"

assert.deepStrictEqual(
  BigDecimal.round(BigDecimal.fromStringUnsafe("145"), { mode: "from-zero", scale: -1 }),
  BigDecimal.fromStringUnsafe("150")
)
assert.deepStrictEqual(
  BigDecimal.round(BigDecimal.fromStringUnsafe("-14.5")),
  BigDecimal.fromStringUnsafe("-15")
)
export const round: {
  (options: { scale?: number; mode?: RoundingMode }): (self: BigDecimal) => BigDecimal
  (n: BigDecimal, options?: { scale?: number; mode?: RoundingMode }): BigDecimal
} = dual(isBigDecimalArgs, (self: BigDecimal, options?: { scale?: number; mode?: RoundingMode }): BigDecimal => {
  const mode = options?.mode ?? "half-from-zero"
  const scale = options?.scale ?? 0

  switch (mode) {
    case "ceil":
      return ceil(self, scale)

    case "floor":
      return floor(self, scale)

    case "to-zero":
      return truncate(self, scale)

    case "from-zero":
      return (isPositive(self) ? ceil(self, scale) : floor(self, scale))

    case "half-ceil":
      return floor(sum(self, make(bigint5, scale + 1)), scale)

    case "half-floor":
      return ceil(sum(self, make(bigint_5, scale + 1)), scale)

    case "half-to-zero":
      return isNegative(self)
        ? floor(sum(self, make(bigint5, scale + 1)), scale)
        : ceil(sum(self, make(bigint_5, scale + 1)), scale)

    case "half-from-zero":
      return isNegative(self)
        ? ceil(sum(self, make(bigint_5, scale + 1)), scale)
        : floor(sum(self, make(bigint5, scale + 1)), scale)
  }

  const halfCeil = floor(sum(self, make(bigint5, scale + 1)), scale)
  const halfFloor = ceil(sum(self, make(bigint_5, scale + 1)), scale)
  const digit = digitAt(halfCeil, scale)

  switch (mode) {
    case "half-even":
      return equals(halfCeil, halfFloor) ? halfCeil : (digit % bigint2 === bigint0) ? halfCeil : halfFloor

    case "half-odd":
      return equals(halfCeil, halfFloor) ? halfCeil : (digit % bigint2 === bigint0) ? halfFloor : halfCeil
  }
})