This release is a pre-release and may not be stable for production use.
decimo
A drop-in replacement for Python's decimal, written in
Mojo.
⚠️ Development release. The API is settled enough to use, but the versions carry a timestamp:
0.14.0.devYYYYMMDDHHMMSS, where0.14.0is the version of the Mojo library the wheel packages. Wheels: macOS arm64 (11 and later), CPython 3.13 and 3.14. Everywhere else, build from source.
Change one import and your program keeps working:
# from decimal import Decimal, getcontext
from decimo import Decimal, getcontext
getcontext().prec = 50
print(Decimal(1) / Decimal(7))
# 0.14285714285714285714285714285714285714285714285714
The two libraries 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 a property that is measured,
not a claim.
How fast is it?
The same benchmark file run against both libraries -- python/benchmarks/compare.py
in the repository, which imports one or the other and runs identical code.
Best of five, on an Apple M-series laptop:
| Program | decimo | decimal | |
|---|---|---|---|
| add/sub/mul/div, 28 digits | 90.6 ns | 73.0 ns | 1.24× slower |
| add/sub/mul/div, 200 digits | 331.8 ns | 409.0 ns | 1.23× faster |
| add/sub/mul/div, 1000 digits | 2.02 µs | 5.89 µs | 2.91× faster |
| compound interest, 150 years | 12.71 µs | 13.08 µs | about the same |
| e from its series, 500 digits | 197.92 µs | 162.75 µs | 1.22× slower |
| sqrt by Newton, 1000 digits | 143.29 µs | 232.29 µs | 1.62× faster |
| pi by Machin, 500 digits | 620.12 µs | 520.17 µs | 1.19× slower |
| parse and print, 1000 digits | 3.28 µs | 2.60 µs | 1.26× slower |
decimo is faster once the numbers are large, and 20-25% behind on small
ones. The small-number gap is not the arithmetic: measured against
libmpdec directly, without an interpreter in the way, decimo is 2-4× faster
at 9 digits and faster at every operation at 1000 digits. What is left is the
cost of the Python call itself -- building the result object and converting
the operands -- which CPython's decimal has had thirty years to shave. See
the benchmarks.
What works
Everything a decimal program normally touches:
- all the operators, including
//,%,divmod()and** getcontext().precandgetcontext().rounding,setcontext(),localcontext()(with keyword overrides),Contextobjects- all the rounding modes:
ROUND_HALF_EVEN,ROUND_HALF_UP,ROUND_HALF_DOWN,ROUND_DOWN,ROUND_UP,ROUND_CEILING,ROUND_FLOOR, exact for arithmetic,quantize,round()andto_integral_value() int(),float(),round(),math.floor/ceil/trunc,hash(),format()Contextyou can compute with:ctx.divide(x, y),ctx.sqrt(x),ctx.quantize(x, y)and the rest, none of them touching the current context- keyword arguments where
decimaltakes them:quantize(exp, rounding=ROUND_HALF_UP),to_integral_value(rounding=...),sqrt(context=...) Decimal((sign, digits, exponent)), soas_tuple()round-tripspow(x, y, modulus), by modular exponentiationquantize,normalize,as_tuple,as_integer_ratio,compare,fma,sqrt,exp,ln,log10,scaleb,adjusted,copy_abs,copy_negate,copy_sign,same_quantum,to_eng_string,max,min- the rest of the specification's surface:
remainder_near,next_plus,next_minus,next_toward,shift,rotate,logical_and,logical_or,logical_xor,logical_invert,logb,compare_total,compare_total_mag,compare_signal,max_mag,min_mag,number_class,to_integral_exact,is_normal,is_subnormal,from_number - the same coercion rules:
intconverts in arithmetic,floatdoes not, and both convert in a comparison copy,deepcopyandpickleZeroDivisionErrorwhere you expect it, and hashes that agree withint,floatanddecimal.Decimal
Two things decimal does not have
decimo.pi(1000) # 1000 digits of pi, by Chudnovsky with binary splitting
decimo.e(50) # 50 digits of e
Without an argument they use the context precision. decimal has neither;
its documentation gives a recipe to write your own.
What does not
decimo refuses these rather than answering differently:
- NaN and infinity. decimo has no non-finite values.
is_nan()andis_infinite()are alwaysFalse. ROUND_05UP. Nothing implements it; setting it raisesNotImplementedError.**under a rounding mode other thanROUND_HALF_EVENis computed nine digits wider and rounded once more, so the last digit can differ fromdecimalwhen the true value lies within10^-9relative of a rounding boundary.sqrt,exp,lnandlog10are always half to even, as they are indecimal, whatever the context says. Arithmetic,quantizeandround()are exact under every mode.//,%,divmod()andremainder_nearwith a long quotient.decimalraisesInvalidOperationwhen the integer quotient has more digits than the precision; decimo answers. The remainder is rounded to the context, as indecimal.Eminonly reaches four methods. Exponents are unbounded, soEminchanges nothing except whatnext_plus(0),next_minus(0),is_subnormal()andnumber_class()say, wheredecimal's answers need a smallest exponent.- Signals and traps.
Context.flagsandContext.trapsexist and stay empty.Inexact,Roundedand the rest are importable but never raised. Emin/Emax. Exponents are unbounded, so nothing ever underflows to zero or overflows to infinity. A loop that waits for a term to become exactly zero will not stop; wait for the sum to stop changing instead.- One context per process, not per thread.
DivisionByZero and InvalidOperation are aliases for ZeroDivisionError
and ValueError, which is what decimo actually raises, so except clauses
written against decimal still catch.
Installing
pip install decimo
Wheels are built for macOS arm64 (macOS 11 and later), for CPython 3.13 and 3.14. On anything else -- Linux included, until its build is verified -- 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/*.whl
Links
Metadata
Release files for decimo 0.14.0.dev20260828205932
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| decimo-0.14.0.dev20260828205932-cp314-cp314-macosx_11_0_arm64.whl | CPython 3.14 | CPython 3.14 | macOS 11.0+ ARM64 | Details |
| decimo-0.14.0.dev20260828205932-cp313-cp313-macosx_11_0_arm64.whl | CPython 3.13 | CPython 3.13 | macOS 11.0+ ARM64 | Details |
Total release size: 1.9 MB
Release files / decimo-0.14.0.dev20260828205932-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | decimo-0.14.0.dev20260828205932-cp314-cp314-macosx_11_0_arm64.whl |
|---|---|
| Size | 929.6 kB |
| Tags | CPython 3.14 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
9a598f547172709cef55861e2dd0616a7695e888a5d4846da934ea7bc9f994ae
|
|
BLAKE2b-256 checksum How to use checksums |
5a3dc93c5dadaf5e98506ffafb5701955990325c04973362c112d49802c4bdf0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / decimo-0.14.0.dev20260828205932-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | decimo-0.14.0.dev20260828205932-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 929.6 kB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
a3e44999feaa24ba92dc60d48ca6492414fa866e435dba34fa1f2f91cef3328d
|
|
BLAKE2b-256 checksum How to use checksums |
32d6ac6fc1bcf1d06d05577616cc170b8462e2bcd5ba6d0c536a61e53235ffa0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logSecurity for decimo 0.14.0.dev20260828205932
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for decimo-0.14.0.dev20260828205932-cp314-cp314-macosx_11_0_arm64.whl
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.