Skip to content

std.decimal

exact decimals (money); coef / 10^scale, i64 coef, max 18 places

pub DecimalError :: errors {
invalid,
overflow,
division_by_zero,
}
  • invalid: text that is no decimal number
  • overflow: coef past i64, or more than 18 places
pub Rounding :: enum {
half_even,
half_up,
half_down,
down,
up,
floor,
ceiling,
}
  • half_even: ties to even (banker’s): 2.5 -> 2, 3.5 -> 4
  • half_up: ties away from zero: 2.5 -> 3, -2.5 -> -3
  • half_down: ties toward zero: 2.5 -> 2
  • down: toward zero: 2.9 -> 2, -2.9 -> -2
  • up: away from zero: 2.1 -> 3, -2.1 -> -3
  • floor: toward -inf: -2.1 -> -3
  • ceiling: toward +inf: 2.1 -> 3
pub MAX_SCALE :: 18u32
pub Decimal :: struct {
coef: i64,
scale: u32,
}
pub format :: fn(self: Decimal, f: *Formatter)

for “{d}” in format strings; keeps all places

pub from_parts :: fn(coef: i64, scale: u32) -> Decimal ! DecimalError

coef / 10^scale; .overflow if scale > 18

pub from_int :: fn(n: i64) -> Decimal
pub zero :: fn() -> Decimal
pub add :: fn(a: Decimal, b: Decimal) -> Decimal ! DecimalError

exact, at the larger scale

pub sub :: fn(a: Decimal, b: Decimal) -> Decimal ! DecimalError

exact, at the larger scale

pub mul :: fn(a: Decimal, b: Decimal) -> Decimal ! DecimalError

scale = a.scale + b.scale; past 18 or too big: drops places (half_even), then .overflow

pub div :: fn(a: Decimal, b: Decimal, scale: u32, mode: Rounding) -> Decimal ! DecimalError

a / b at scale places, rounded by mode

pub round :: fn(d: Decimal, scale: u32, mode: Rounding) -> Decimal ! DecimalError

more places is exact; fewer rounds by mode

pub neg :: fn(d: Decimal) -> Decimal ! DecimalError
pub abs :: fn(d: Decimal) -> Decimal ! DecimalError
pub normalize :: fn(d: Decimal) -> Decimal

strips trailing zeros: 2.500 -> 2.5, 3.00 -> 3

pub cmp :: fn(a: Decimal, b: Decimal) -> i32

-1, 0, 1; ignores scale (2.50 == 2.5)

pub eq :: fn(a: Decimal, b: Decimal) -> bool
pub less :: fn(a: Decimal, b: Decimal) -> bool
pub is_zero :: fn(d: Decimal) -> bool
pub is_negative :: fn(d: Decimal) -> bool
pub parse :: fn(text: []const u8) -> Decimal ! DecimalError

sign, digits, one point, optional exponent; scale = places written; .invalid, .overflow

pub to_text :: fn(d: Decimal, out: []u8) -> []const u8

keeps all places (19.90 stays 19.90); slice of out; 48 bytes always enough

pub to_f64 :: fn(d: Decimal) -> f64

nearest f64; exact to ~15 significant digits

pub from_f64 :: fn(x: f64, scale: u32) -> Decimal ! DecimalError

rounds half-even to scale places; floats are binary, not for exact work

pub sum :: fn(xs: []const Decimal) -> Decimal ! DecimalError

exact, at the largest scale