Reference · Decimals and money

dec

signature
dec(any) -> dec | error(str)

What it does

The value as a decimal: an exact number with a fixed count of decimals, for money and whatever else is counted in cents. Text is read exactly and keeps its digits (dec("1.50") is 1.50, not 1.5); an int is itself; a float goes through its shortest text, so dec(0.1) is 0.1, not 0.1000000000000000055…, a tie taking the even digit as JavaScript does, so money from a float agrees on the server and in the browser. What cannot be a decimal is an error value, not a runtime error, so the result can be checked with is_err or given a default with ??. Arithmetic between decimals and ints is exact; a float next to a decimal is a runtime error.

Examples

print(dec("1.50"), dec(42), dec(0.1), dec("-0.01"))print(dec("1.50") + dec("2"), dec("1.10") * 3, dec("10") / 4)print(dec(0.1) + dec(0.2) == dec("0.3"), 0.1 + 0.2)print(dec("1.50") == dec("1.5"), str(dec("1.50")))
output
1.50 42 0.1 -0.013.50 3.30 2.5true 0.30000000000000004true 1.50

Edge cases

print(dec("1.50") * dec("1.0"), dec("12.5") == dec("12.50"))print(dec("  7.25 "), dec("1e3"), dec("1,5"), dec(""))print(dec("79228162514264337593543950335"))print(dec("79228162514264337593543950336"), dec(1e29), dec(float("nan")))print(dec(null), dec(true), dec("1") / 3)print([dec("1.50")], { price: dec("1.50") })
output
1.500 true7.25 1000 err("not a decimal: \"1,5\"") err("not a decimal: \"\"")79228162514264337593543950335err("not a decimal: \"79228162514264337593543950336\"") err("cannot convert float to dec: it is too large, or not a number") err("cannot convert float to dec: it is too large, or not a number")err("cannot convert null to dec") err("cannot convert bool to dec") 0.3333333333333333333333333333[1.50m] { price: 1.50m }

Errors

Text, a float or another value that is not a decimal gives an error value whose text says what was given. Mixing a decimal with a float (dec("1.5") + 0.5), a result whose whole part no longer fits (decimal overflow) and dividing by zero are runtime errors, not error values: they stop the request.

let d = dec("abc")print(is_err(d), d.error, dec("abc") ?? dec(0))
output
true not a decimal: "abc" 0
this one fails
print(dec("1.5") + 0.5)
output
line 1: cannot add dec and float: a dec is exact and a float is not, so convert one with dec(x) or float(x)
this one fails
print(dec("79228162514264337593543950335") + dec("1"))
output
line 1: decimal overflow

Chaining

In a pipeline the value comes first, so dec takes it as its only argument. A list of text becomes a list of decimals with map(dec), and sum keeps the sum exact:

print("19.99" | dec | round(1))print(["1.50", "2.25"] | map(dec) | sum)print(["1.5", "x", "2"] | map(dec) | filter((v) => !is_err(v)))
output
20.03.75[1.5m, 2m]

See also

int, float, str, round, is_err, money.of, format_number

Thread
8Useful? Like it, or add to its thread below.

Thread 0 posts

On dec(): questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.

    Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo