An arbitrary-precision integer and decimal library for
Mojo, also with a 128-bit fixed-point decimal
type, inspired by Python's int and Decimal. Install it with
pixi add decimo.
Comes with an interactive arbitrary-precision calculator (REPL + one-shot mode)
powered by ArgMojo. Install it with
brew install forfudan/tap/decimo.
The same library is packaged for Python as a near drop-in for the standard
library's decimal, and a superset of it: the whole of its method surface,
plus pi(), e() and a 128-bit decimal type. Install it with
pip install decimo.
| Type | Alias | Information | Layout |
|---|---|---|---|
BigInt |
BInt |
Equivalent to Python's int |
Base-2^64 |
BigDecimal |
BDec, Decimal |
Equivalent to Python's decimal.Decimal |
Base-10^18 |
Decimal128 |
Dec128 |
128-bit fixed-precision decimal type | 32-bit words |
BigFloat |
Float |
Arbitrary-precision floating-point type | MPFR/GMP |

Base-ten arithmetic, integers with no width limit, and an expression evaluator
Decimo provides an arbitrary-precision integer and decimal library for Mojo. It delivers exact calculations for financial modeling, scientific computing, and applications where floating-point approximation errors are unacceptable. Beyond basic arithmetic, the library includes advanced mathematical functions with guaranteed precision.
For Pythonistas, decimo.BigInt to Mojo is like int to Python, and
decimo.BigDecimal to Mojo is like decimal.Decimal to Python.
decimo.Decimal128 to Mojo is like System.Decimal to C# or rust_decimal to
Rust.
The core types are1:
- An arbitrary-precision signed integer type
BigInt2 (aliasBInt), which is a Mojo-native equivalent of Python'sint. - An arbitrary-precision decimal implementation (
BigDecimal) (aliasDecimal) allowing for calculations with unlimited digits and decimal places3, which is a Mojo-native equivalent of Python'sdecimal.Decimal. - A 128-bit fixed-point decimal implementation (
Decimal128) (aliasDec128) supporting up to 29 significant digits with a maximum of 28 decimal places4, which is a Mojo-native equivalent of C#'sSystem.Decimalor Rust'srust_decimal. - An arbitrary-precision floating-point implementation (
BigFloat) backed by the GNU MPFR library, supporting computations with configurable precision and a wide exponent range. UnlikeBigDecimal, which uses base-10 arithmetic,BigFloatuses binary floating-point internally. This type is optional and requires MPFR/GMP to be installed on the user's system.
Decimo is fast: at a million digits pi() is nearly twelve times quicker than
pure-Python mpmath, BigInt multiplication is fifteen times quicker than
CPython's int,
and small BigDecimal operations are close to libmpdec, the C library behind
Python's decimal. The measured numbers, with the commit they were taken on,
are in docs/benchmarks.md; pixi run benchdoc regenerates
them.
Decimo combines "Decimal" and "Mojo" - reflecting its purpose and implementation language. "Decimo" is also a Latin word meaning "tenth" and is the root of the word "decimal".
decimo is a command-line calculator built on the Decimo library and powered by
ArgMojo. Run it with no arguments for an
interactive REPL, or pass an expression / file / piped stdin for one-shot
evaluation. The binary is self-contained β no Mojo or Pixi needed on the user's
machine. See the user manual for the full
reference, and the Quick start below for a taste.

Ask for as many significant digits as you like

Everything decimal has, and things it does not
The Mojo library is also compiled into a Python extension and published on PyPI,
where it stands in for the standard library's decimal. Change one import and
a decimal program keeps working:
# from decimal import Decimal, getcontext
from decimo import Decimal, getcontext
getcontext().prec = 50
print(Decimal(1) / Decimal(7))
# 0.14285714285714285714285714285714285714285714285714The two agree digit for digit. The test suite checks every operation against
the standard library rather than against a table of expected strings, so
"agrees with decimal" is measured rather than claimed.
Nothing is missing: every method decimal.Decimal has, decimo.Decimal has
too. And it goes further. pi() and e() are there, which decimal has
neither of. sqrt, exp, ln and log10 take a rounding= argument, where
decimal ignores the context mode for those and always rounds half to even.
Decimal128 brings trigonometry, cbrt, root and the IEEE 754 interchange
bytes with it. And it is faster once the numbers are large β 2.9x at a
thousand digits β 20-25% behind on small ones, where what is left is the cost
of the Python call rather than the arithmetic.
Where it is not a drop-in it refuses rather than answers differently: no NaN
or infinity, no ROUND_05UP, no signals or traps, and one context per process
rather than per thread. See python/README.md for the
full list with the reasoning, and the
Python quick start below for a taste.
This repository includes a built-in TOML parser
(decimo.toml), a lightweight pure-Mojo implementation supporting TOML v1.0. It
parses configuration files and test data, supporting basic types, arrays, and
nested tables. While created for Decimo's testing framework, it offers
general-purpose structured data parsing with a clean, simple API.
Decimo is available in the modular-community
https://repo.prefix.dev/modular-community package repository. To access this
repository, add it to your channels list in your pixi.toml file:
channels = ["https://conda.modular.com/max", "https://repo.prefix.dev/modular-community", "conda-forge"]Then, you can install Decimo using any of these methods:
-
From the
pixiCLI, run the commandpixi add decimo. This fetches the latest version and makes it immediately available for import. -
In the
mojoproject.tomlfile of your project, add the following dependency:decimo = ">=0.14.0, <0.15.0"
Then run
pixi installto download and install the package. -
For the latest development version in the
mainbranch, clone this GitHub repository and build the package locally using the commandpixi run package.
Package versions and Mojo compatibility
The following table summarizes the package versions and their corresponding Mojo versions:
| library | version | Mojo version | package manager |
|---|---|---|---|
decimojo |
v0.1.0 | ==25.1 | magic |
decimojo |
v0.2.0 | ==25.2 | magic |
decimojo |
v0.3.0 | ==25.2 | magic |
decimojo |
v0.3.1 | >=25.2, <25.4 | pixi |
decimojo |
v0.4.x | ==25.4 | pixi |
decimojo |
v0.5.0 | ==25.5 | pixi |
decimojo |
v0.6.0 | ==0.25.7 | pixi |
decimojo |
v0.7.0 | ==0.26.1 | pixi |
decimo |
v0.8.0 | ==0.26.1 | pixi |
decimo |
v0.9.0 | ==0.26.2 | pixi |
decimo |
v0.10.0 | ==1.0.0b1 | pixi |
decimo |
v0.11.0 | ==1.0.0b2 | pixi |
decimo |
v0.12.0 | >=1.0.0, <1.1.0 | pixi |
decimo |
v0.13.0 | >=1.0.0, <1.1.0 | pixi |
decimo |
v0.14.0 | >=1.0.0, <1.1.0 | pixi |
The decimo CLI is distributed via the
forfudan/tap Homebrew tap.
Pre-built binaries are available for macOS arm64 (Apple Silicon) and
Linux x86_64, and ship with the Mojo runtime libraries bundled β you do not
need Mojo or Pixi installed.
brew install forfudan/tap/decimo
decimo --versionOr tap once and use the bare formula name:
brew tap forfudan/tap
brew install decimoTo upgrade to a later release:
brew update && brew upgrade decimopip install decimoWheels are built for macOS arm64 (macOS 11 and later) and for Linux on x86_64 and arm64 (glibc 2.35 and later), for CPython 3.13 and 3.14. Nothing else is needed β the Mojo runtime libraries travel inside the wheel. On any other platform, build from source with pixi:
git clone https://github.com/forfudan/decimo && cd decimo
pixi run -e py314 release # or py313; the wheel lands in python/dist/
pip install python/dist/*.whlYou can start using Decimo by importing the decimo module. An easy way to do
this is to import everything from the prelude module, which provides the most
commonly used types.
from decimo.prelude import *This will import the following types or aliases into your namespace:
BigInt(and its aliasBInt): An arbitrary-precision signed integer type, equivalent to Python'sint.BigDecimal(and its aliasesBDec,Decimal): An arbitrary-precision decimal type, equivalent to Python'sdecimal.Decimal.Decimal128(and its aliasDec128): A 128-bit fixed-precision decimal type.RoundingMode: An enumeration for rounding modes.ROUND_DOWN,ROUND_HALF_UP,ROUND_HALF_EVEN,ROUND_UP,ROUND_CEILING,ROUND_FLOOR: Constants for common rounding modes.
BigDecimal β arbitrary precision, and how to set it
Here are some examples showcasing the arbitrary-precision feature of the
BigDecimal (Decimal) type. For some mathematical operations, the default
precision (number of significant digits) is set to 28. You can change the
precision by passing the precision argument to the function. This default
precision will be configurable globally in future when Mojo supports global
variables.
from decimo.prelude import *
def main() raises:
var a = BigDecimal("123456789.123456789")
var b = Decimal("1234.56789") # Alias of BigDecimal
# === Basic Arithmetic === #
print(a + b) # 123458023.691346789
print(a - b) # 123455554.555566789
print(a * b) # 152415787654.32099750190521
print(a.true_divide(b + 1)) # 99919.06565608207008357913866
# === Exponential Functions === #
print(a.sqrt(precision=80))
# 11111.111066111110969430554981749302328338130654689094538188579359566416821203641
print(a.cbrt(precision=80))
# 497.93385938415242742001134219007635925452951248903093962731782327785111102410518
print(a.root(b, precision=80))
# 1.0152058862996527138602610522640944903320735973237537866713119992581006582644107
print(a.power(b, precision=80))
# 3.3463611024190802340238135400789468682196324482030786573104956727660098625641520E+9989
print(a.exp(precision=80))
# 1.8612755889649587035842377856492201091251654136588338983610243887893287518637652E+53616602
print(a.log(b, precision=80))
# 2.6173300266565482999078843564152939771708486260101032293924082259819624360226238
print(a.ln(precision=80))
# 18.631401767168018032693933348296537542797015174553735308351756611901741276655161
# === Trigonometric Functions === #
print(a.sin(precision=200))
# 0.99985093087193092464780008002600992896256609588456
# 91036188395766389946401881352599352354527727927177
# 79589259132243649550891532070326452232864052771477
# 31418817041042336608522984511928095747763538486886
print(b.cos(precision=1000))
# -0.9969577603867772005841841569997528013669868536239849713029893885930748434064450375775817720425329394
# 9756020177557431933434791661179643984869397089102223199519409695771607230176923201147218218258755323
# 7563476302904118661729889931783126826250691820526961290122532541861737355873869924820906724540889765
# 5940445990824482174517106016800118438405307801022739336016834311018727787337447844118359555063575166
# 5092352912854884589824773945355279792977596081915868398143592738704592059567683083454055626123436523
# 6998108941189617922049864138929932713499431655377552668020889456390832876383147018828166124313166286
# 6004871998201597316078894718748251490628361253685772937806895692619597915005978762245497623003811386
# 0913693867838452088431084666963414694032898497700907783878500297536425463212578556546527017688874265
# 0785862902484462361413598747384083001036443681873292719322642381945064144026145428927304407689433744
# 5821277763016669042385158254006302666602333649775547203560187716156055524418512492782302125286330865
# === Internal representation of the number === #
(
Decimal(
"3.141592653589793238462643383279502884197169399375105820974944"
).power(2, precision=60)
).print_internal_representation()
# Internal Representation Details of BigDecimal
# ----------------------------------------------
# number: 9.8696044010893586188344909998
# 761511353136994072407906264133
# 5
# coefficient: 986960440108935861883449099987
# 615113531369940724079062641335
# negative: False
# scale: 59
# word 0: 940724079062641335
# word 1: 99987615113531369
# word 2: 440108935861883449
# word 3: 986960
# ----------------------------------------------BigInt β arbitrary-precision signed integers
A quick tour of the main methods of the BigInt (BInt) type.
from decimo.prelude import *
def main() raises:
# === Construction ===
var a = BigInt("12345678901234567890") # From string
var b = BigInt(12345) # From integer
var c = BInt("1991_10,18") # From string with separators and spaces
print(a, b, c)
# === Basic Arithmetic ===
print(a + b) # Addition: 12345678901234580235
print(a - b) # Subtraction: 12345678901234555545
print(a * b) # Multiplication: 152407406035740740602050
# === Division Operations ===
print(a // b) # Floor division: 1000054994024671
print(a.truncate_divide(b)) # Truncate division: 1000054994024671
print(a % b) # Modulo: 4395
# === Power Operation ===
print(BigInt(2).power(10)) # Power: 1024
print(BigInt(2) ** 10) # Power (using ** operator): 1024
# === Comparison ===
print(a > b) # Greater than: True
print(a == BigInt("12345678901234567890")) # Equality: True
print(a.is_zero()) # Check for zero: False
# === Type Conversions ===
print(String(a)) # To string: "12345678901234567890"
# === Sign Handling ===
print(-a) # Negation: -12345678901234567890
print(
abs(BigInt("-12345678901234567890"))
) # Absolute value: 12345678901234567890
print(a.is_negative()) # Check if negative: False
# === Extremely large numbers ===
# 3600 digits // 1800 digits
print(BigInt("123456789" * 400) // BigInt("987654321" * 200))
# === Greatest common divisor ===
print(a.gcd(b)) # Greatest common divisor: 15
print(a.gcd(c)) # Greatest common divisor: 6Decimal128 β a fixed 128-bit decimal
A quick tour of the main methods of the Decimal128 (Dec128) type.
from decimo.prelude import *
def main() raises:
# === Construction ===
# Decimal128 and Dec128 are aliases
var a = Decimal128("123.45") # From string
var b = Decimal128(123) # From integer
var c = Dec128(123, 2) # Integer with scale (1.23)
var d = Dec128.from_float_scalar(3.14159) # From floating-point
# === Basic Arithmetic ===
print(a + b) # Addition: 246.45
print(a - b) # Subtraction: 0.45
print(a * b) # Multiplication: 15184.35
print(a / b) # Division: 1.0036585365853658536585365854
# === Rounding & Precision ===
print(a.round(1)) # Round to 1 decimal place, half to even: 123.4
print(a.quantize(Dec128("0.01"))) # Format to 2 decimal places: 123.45
print(a.round(0, RoundingMode.ROUND_DOWN)) # Round down to integer: 123
# === Comparison ===
print(a > b) # Greater than: True
print(a == Dec128("123.45")) # Equality: True
print(a.is_zero()) # Check for zero: False
print(Dec128("0").is_zero()) # Check for zero: True
# === Type Conversions ===
print(Float64(a)) # To float: 123.45
print(a.to_int()) # To integer: 123
print(a.to_string()) # To string: "123.45"
print(a.coefficient()) # Get coefficient: 12345
print(a.scale()) # Get scale: 2
# === Mathematical Functions ===
print(Dec128("2").sqrt()) # Square root: 1.4142135623730950488016887242
print(Dec128("100").root(3)) # Cube root: 4.641588833612778892410076351
print(Dec128("2.71828").ln()) # Natural log: 0.9999993273472820031578910056
print(Dec128("10").log10()) # Base-10 log: 1
print(
Dec128("16").log(Dec128("2"))
) # Log base 2: 3.9999999999999999999999999999
print(Dec128("10").exp()) # e^10: 22026.465794806716516957900645
print(Dec128("2").power(10)) # Power: 1024
# === Sign Handling ===
print(-a) # Negation: -123.45
print(abs(Dec128("-123.45"))) # Absolute value: 123.45
print(Dec128("123.45").is_negative()) # Check if negative: False
# === Special Values ===
print(Dec128.PI()) # Ο constant: 3.1415926535897932384626433833
print(Dec128.E()) # e constant: 2.7182818284590452353602874714
print(Dec128.ONE()) # Value 1: 1
print(Dec128.ZERO()) # Value 0: 0
print(Dec128.MAX()) # Maximum value: 79228162514264337593543950335
# === Convenience Methods ===
print(Dec128("123.400").is_integer()) # Check if integer: False
print(a.number_of_significant_digits()) # Count significant digits: 5
print(
Dec128("12.34").to_scientific_string()
) # Scientific notation: 1.234E+1For an interactive session, just type decimo:

A real session: ans, the : settings system, and inline settings
$ decimo
Decimo β an arbitrary-precision calculator π₯
Type ? for help, : for settings, :q to quit.
Precision: 50. Rounding: ROUND_HALF_EVEN.
decimo> 2 ^ 10
1024
decimo> ans / 4
256
decimo> 1/7
0.14285714285714285714285714285714285714285714285714
decimo> :100
Current settings:
Precision : 100
Scientific : off
Engineering : off
Pad : off
Delimiter : (none)
Rounding mode : ROUND_HALF_EVEN
decimo> pi
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
decimo> sqrt(e) / ln(10) + sin(-1.23) :200 e he delimiter _
-226.458_251_870_114_348_807_514_569_584_297_293_353_150_959_525_480_515_507_901_779_719_167_225_208_528_825_475_488_261_072_148_336_432_171_617_635_953_314_758_797_226_777_458_915_435_649_950_836_584_843_137_886_028_274_720_793_979_517_570_004_978_334_405_953_342_64E-3
decimo> :qThe REPL keeps the last result in ans, lets you define variables
(name = expr), and exposes settings via :-prefixed commands (e.g. :100 for
precision, :s for scientific, :d for ROUND_DOWN). Input is case-insensitive.
Quit with :q, exit, or Ctrl-D.
As an innovative feature, Decimo supports multiple settings in a single line.
They can either be global (persist across calculations) or local (apply only to
the current expression). In the example above, :200 e he delimiter _ means
"evaluate the expression with precision 200 (200), scientific notation with
engineering exponent (e), round half to even (he), and use _ as the digit
delimiter in the output (delimiter _)". The settings apply only to the current
expression and do not affect subsequent calculations.
For one-shot evaluation, pass an expression on the command line, pipe it via stdin, or read from a file:
$ decimo "sqrt(2)" -P 30
1.41421356237309504880168872421
$ echo "1/3" | decimo -P 50
0.33333333333333333333333333333333333333333333333333
$ decimo -F expressions.dm -P 80Useful flags: -P N (precision), -R MODE (rounding), -S / -E (scientific
/ engineering), --pad, --delimiter, --completions {bash,zsh,fish}. Run
decimo --help for the full list.
Everything a decimal program normally touches is there, under the same names:
from decimo import Decimal, Decimal128, getcontext, localcontext, ROUND_FLOOR
getcontext().prec = 28
# The operators, the context, and the methods, as in `decimal`.
Decimal("0.1") + Decimal("0.2") # 0.3, exactly
Decimal(1) / Decimal(7) # to the context precision
Decimal("2.675").quantize(Decimal("0.01"))
divmod(Decimal(17), Decimal(5)) # (3, 2)
# A context you can compute in, without touching the global one.
with localcontext(prec=50):
print(Decimal(2).sqrt())
# Three things `decimal` does not have.
import decimo
decimo.pi(1000) # Chudnovsky with binary splitting
decimo.e(50)
Decimal(2).sqrt(rounding=ROUND_FLOOR) # and exp, ln, log10, correctly rounded
# The fixed-width type for money: 16 bytes that own nothing.
price = Decimal128("19.99")
(price * 3).quantize(Decimal128("0.01")) # 59.97A mixed expression settles in the wider type β Decimal128 + Decimal is a
Decimal, either way round β and the hashes of Decimal, Decimal128,
int, float and decimal.Decimal all agree, so the five are
interchangeable as dictionary keys.
What decimo refuses rather than answering differently: NaN and infinity,
ROUND_05UP, signals and traps, and one context per process rather than per
thread. The full list, with the reasoning, is in
python/README.md.
Financial calculations and data analysis require precise decimal arithmetic that floating-point numbers cannot reliably provide. As someone working in finance and credit risk model validation, I needed a dependable correctly-rounded, fixed-precision numeric type when migrating my personal projects from Python to Mojo.
Since Mojo currently lacks a native Decimal type in its standard library, I decided to create my own implementation to fill that gap.
This project draws inspiration from several established decimal implementations
and documentation, e.g.,
Python built-in Decimal type,
Rust rust_decimal crate,
Microsoft's Decimal implementation,
General Decimal Arithmetic Specification,
etc. Many thanks to these predecessors for their contributions and their
commitment to open knowledge sharing.
Rome wasn't built in a day. Decimo is currently under active development. It has successfully progressed through the "make it work" phase and the "make it right", and is now well into the "make it fast" phase.
The BigInt type is fully implemented and optimized. It is measured against
GMP, timed in C, rather than against CPython's int, which is reached through
the interpreter and so loses on call overhead before the arithmetic starts.
Bug reports and feature requests are welcome! If you encounter issues, please file them here.
The source tree
decimo/
βββ src/ # All source code
β βββ decimo/ # Core library (mojo pre-compiled package)
β β βββ bigdecimal/ # Arbitrary-precision decimal (Decimal)
β β βββ bigint/ # Arbitrary-precision signed integer (BigInt)
β β βββ bigint10/ # Base-10 signed integer (BigInt10)
β β βββ biguint/ # Base-10 unsigned integer (BigUInt)
β β βββ bigfloat/ # Arbitrary-precision binary float (MPFR)
β β βββ rational/ # Exact rational number (Rational)
β β βββ decimal128/ # 128-bit fixed-precision decimal (Dec128)
β β βββ expression/ # Expression engine behind `decimo.eval()`
β β β βββ tokenizer.mojo # Lexer: expression β tokens
β β β βββ parser.mojo # Shunting-yard: infix β RPN
β β β βββ evaluator.mojo # RPN evaluator using Decimal
β β βββ numerals/ # Numeral systems (e.g. Chinese numerals)
β β βββ toml/ # TOML parser (decimo.toml)
β β βββ ... # Shared utilities (str, errors, rounding)
β βββ cli/ # CLI calculator application
β βββ main.mojo # Entry point (ArgMojo CLI)
β βββ limo/ # Line editor used by the REPL
β βββ calculator/ # Presentation layer (display, io, repl, settings)
βββ python/ # The library packaged for Python (PyPI: decimo)
β βββ decimo_module.mojo # The Python extension, written in Mojo
β βββ src/decimo/ # The `decimo` Python package around it
β βββ tests/ # Checked against the standard library's `decimal`
βββ tests/ # Unit tests (one subfolder per module)
β βββ bigdecimal/
β βββ bigint/
β βββ biguint/
β βββ decimal128/
β βββ expression/ # Expression engine tests
β βββ numerals/ # Numeral system tests
β βββ cli/ # CLI calculator tests
β βββ toml/
βββ benches/ # Benchmarks (one subfolder per module)
βββ docs/ # Documentation and design notes
βββ pixi.toml # Project configuration and tasks
src/decimo/ is a Mojo package β it is compiled with mojo precompile and can
be imported by external projects. The expression engine (decimo.expression),
the numeral systems (decimo.numerals), and the TOML parser (decimo.toml) are
included as subpackages. src/cli/ is an application that consumes the decimo
package and compiles to a standalone binary via mojo build. python/ compiles
the same package into a CPython extension and wraps it in a Python package, and
is what pip install decimo fetches.
After cloning the repo onto your local disk, you can:
- Use
pixi run testto run all tests, orpixi run test <suite>for one suite (pixi run test --listshows them). - Use
pixi run testclito run CLI calculator tests. - Use
pixi run testpyto build the Python extension and run its tests against the standard library'sdecimal. - Use
pixi run benchto run benchmarks. - Use
pixi run benchdocto regenerate docs/benchmarks.md against libmpdec, GMP, CPython and MPFR. Needsmpdecimalandgmpinstalled for the C comparisons; the reference libraries for thepi()table live in the optionalbenchdocenvironment (pixi install -e benchdoc). - Use
pixi run buildclito compile the CLI calculator to a./decimobinary. - Use
pixi run organize_importsto group, sort and de-duplicate the imports in every.mojofile: four blocks separated by a blank line β the Mojo standard library, third-party packages,decimoitself, and modules reached through-I.--checkis what the pre-commit hook runs. A file whose import block holds a comment is left alone and named as skipped;scripts/organize_mojo_imports.py's docstring says why, and why--remove-unusedis opt-in. - Use
pixi run check_import_fixed_pointafter changing the organizer or the Mojo version: it asserts that the organizer andmojo formatdo not undo each other's work.
If you find Decimo useful, consider listing it in your citations.
@software{Zhu.2026,
author = {Zhu, Yuhao},
year = {2026},
title = {Decimo: An arbitrary-precision integer and decimal library for Mojo},
url = {https://github.com/forfudan/decimo},
version = {0.14.0},
note = {Computer Software}
}This repository and its contributions are licensed under the Apache License v2.0.
The BigFloat type optionally uses the
GNU MPFR Library (LGPLv3+) and
GMP (LGPLv3+ or GPLv2+) at runtime. Decimo does not
include or distribute any MPFR/GMP source code or binaries β they are loaded via
dlopen only if the user has independently installed them. All other Decimo
types work without any external dependencies. See the NOTICE file
for details.
Footnotes
-
The auxiliary types include a base-10 arbitrary-precision signed integer type (
BigInt10) and a base-10 arbitrary-precision unsigned integer type (BigUInt) supporting unlimited digits5.BigUIntis used as the internal representation forBigInt10andDecimal. β© -
The
BigIntimplementation uses a base-2^64 representation with a little-endian format, where the least significant word is stored at index 0. Each word is aUInt64, allowing for efficient storage and arithmetic operations on large integers. This design choice optimizes performance for binary computations while still supporting arbitrary precision. β© -
Built on the
BigUIntimplementation, Decimal supports arbitrary precision for both the integer and fractional parts, similar todecimalandmpmathin Python,java.math.BigDecimalin Java, etc. β© -
The
Dec128type can represent values with up to 29 significant digits and a maximum of 28 digits after the decimal point. When a value exceeds the maximum representable value (2^96 - 1), Decimo either raises an error or rounds the value to fit within these constraints. For example, the significant digits of8.8888888888888888888888888888(29 eights total with 28 after the decimal point) exceeds the maximum representable value (2^96 - 1) and is automatically rounded to8.888888888888888888888888889(28 eights total with 27 after the decimal point). Decimo'sDec128type is similar toSystem.Decimal(C#/.NET),rust_decimalin Rust,DECIMAL/NUMERICin SQL Server, etc. β© -
The BigInt10 implementation uses a base-10 representation for users (maintaining decimal semantics), while internally using an optimized base-10^18 storage system for efficient calculations. This approach balances human-readable decimal operations with high-performance computing. It provides both floor division (round toward negative infinity) and truncate division (round toward zero) semantics, enabling precise handling of division operations with correct mathematical behavior regardless of operand signs. β©