# dee
[](https://hex.pm/packages/dee)
[](https://hexdocs.pm/dee/)
[](https://github.com/kantox/dee/actions/workflows/test.yml)
Arbitrary precision decimal arithmetic for Gleam. A pure Gleam implementation of [Elixir's Decimal](https://hexdocs.pm/decimal) library that works identically on both Erlang and JavaScript targets.
```gleam
import dee/decimal
pub fn main() {
// Floating point: 0.1 + 0.2 = 0.30000000000000004
// Decimal: 0.1 + 0.2 = 0.3
let assert Ok(a) = decimal.from_string("0.1")
let assert Ok(b) = decimal.from_string("0.2")
let sum = decimal.add(a, b)
decimal.to_string(sum)
// -> "0.3"
}
```
## Installation
```sh
gleam add dee
```
## Features
- **Elixir Decimal compatible**: API and behavior aligned with [Elixir's Decimal](https://hexdocs.pm/decimal) as the reference implementation
- **Arbitrary precision**: No overflow or precision loss for any size numbers
- **Cross-platform**: Works identically on Erlang and JavaScript targets
- **Pure Gleam**: Single codebase, no FFI, no Elixir dependency
## Quick Start
```gleam
import dee/decimal.{type Decimal}
pub fn calculate_tax(price: Decimal, rate: Decimal) -> Decimal {
decimal.multiply(price, rate)
|> decimal.round(2, decimal.HalfUp)
}
pub fn main() {
let assert Ok(price) = decimal.from_string("19.99")
let assert Ok(tax_rate) = decimal.from_string("0.0825")
let tax = calculate_tax(price, tax_rate)
decimal.to_string(tax)
// -> "1.65"
}
```
## Elixir Decimal Compatibility
This library uses [Elixir's Decimal](https://hexdocs.pm/decimal) as its reference implementation. The API, arithmetic behavior, rounding modes, and special value handling are designed to match. Code ported between the two libraries should produce identical results.
### Why Pure Gleam Instead of FFI?
Using FFI to Elixir's Decimal would only work on the Erlang target. A pure Gleam implementation gives us a single codebase that works identically on both Erlang and JavaScript targets, with no Elixir dependency.
Arbitrary precision is achieved via the [`bigi`](https://hexdocs.pm/bigi/) library, which uses native BEAM integers on Erlang and native `BigInt` on JavaScript.
### Interoperability
Both libraries use the same mathematical representation (`sign * coefficient * 10^exponent`) with the same semantics for NaN, Infinity, and signed zero. The default context matches Elixir's: 28 digits of precision with HalfUp rounding.
While the runtime representations differ (Gleam opaque type vs Elixir struct), converting between them on the BEAM is straightforward via `to_string`/`from_string` or by mapping component fields through `from_parts`, `sign`, and `exponent`.
## Development
```sh
gleam test --target erlang # Run tests on Erlang
gleam test --target javascript # Run tests on JavaScript
gleam docs build # Build documentation
```
## Further Documentation
Full API documentation is available at [https://hexdocs.pm/dee](https://hexdocs.pm/dee).