20260701 (v0.11.0)
Decimo v0.11.0 retargets the codebase to Mojo v1.0.0b2, adds the factorial() and permutation() functions to BigInt and BigDecimal, and includes a series of performance improvements for BigDecimal and BigUInt arithmetic. It also renames the BigDecimal round_to_precision APIs to *_inplace, which is a breaking change for code that calls them directly.
⭐️ New in v0.11.0
Number-theoretic functions:
factorial()forBigIntandBigDecimal— a standalone function in the newspecialmodules and an instance method on both types.BigDecimal.factorial(precision=0)returns the exact value by default and a rounded value when a positiveprecisionis given. The exact path uses balanced binary splitting (product_range) with in-place single-word multiplication at the recursion leaves, which is much faster than a naive running product for large arguments (PR #254, #255, #256).permutation()— the number ofk-permutations ofn,P(n, k) = n! / (n − k)!, likewise provided as aspecial-module function and as a method onBigInt/BigDecimal(with optional rounding forBigDecimal). ForBigInt,nis restricted to a single word (PR #255).
🦋 Changed in v0.11.0
Mojo v1.0.0b2 migration (PR #257):
- Retarget the codebase to Mojo v1.0.0b2, and bump the Pixi dependencies to
mojo >=1.0.0b2andargmojo 0.7.0. - Switch packaging from the deprecated
mojo package/.mojopkgtomojo precompile/.mojocacross the Pixi tasks, CI workflows, and helper scripts. - Update the
Decimal128string formatter to theStringSlice(unsafe_from_utf8=Span(...))constructor, replacing the deprecatedStringSlice(ptr=, length=)form.
BigDecimal — rounding API rename:
- The free function
round_to_precisionand the matchingBigDecimalmethod are renamed toround_to_precision_inplace, which makes their mutating semantics explicit, and now run through an allocation-free in-place path. The out-of-place, Python-compatibleBigDecimal.round(ndigits=...)is unchanged. Code that calls the renamed APIs must update its import and call sites (PR #245).
Performance:
BigDecimaladdition / subtraction — a same-scale fast path avoids the scale-alignment work when both operands share a scale (and, foradd, a sign) (PR #247).BigDecimalmultiplication — compute the exact coefficient product in a single pass and round only afterwards when a precision is requested, removing a recursive call and a duplicated zero fast-path (PR #248).BigDecimaldivision and string conversion — fewer allocations individe,from_stringparsing, andto_stringrendering, through in-place batching and an exact-size output buffer (PR #249).BigUIntmultiplication — a deferred-carry (product-scanning) schoolbook path is selected once the operand size crosses a threshold; the Toom-3 cutoff is retuned and the "school" helpers are renamed to "schoolbook" (PR #250).- Logarithm constants —
compute_ln2andcompute_ln1d25fold their series factor into a singleUInt32division per term, andBigUInt.floor_divide_by_uint32hoists its buffer pointers out of the inner loop (PR #251).
Code quality and tooling:
BigInt.from_integral_scalar()is simplified into one generic word-peeling loop over any integral scalar type, backed by a newunsigned_counterparttype helper (PR #253).- The
BigIntbenchmarks are refactored into a cross-language harness that comparesdecimo.BigIntagainst Pythonintand Rustnum-bigint, with a Markdown report aggregator (PR #252). - Documentation — added
Raises:sections across the public API, replaced banner-style header comments with module docstrings, and introduced local import aliases in place of fully-qualified references (PR #245, #246).
What's Changed
- [core][decimal] Create alias for imports + Make
round_to_precisionallocation-free by @forfudan in #245 - [core][doc] Add raises to docstrings and fix related issues by @forfudan in #246
- [decimal] Add same-scale hot path for
add()andsubtract()by @forfudan in #247 - [decimal] Implement single pass precise multiplication by @forfudan in #248
- [decimal] Optimize divide and string conversion with in-place batching by @forfudan in #249
- [biguint] Add deferred-carry multiplication to
BigUIntby @forfudan in #250 - [decimal] Use exact-reciprocal divide for calculating ln(2) and ln(1.25) by @forfudan in #251
- [bigint][bench] Refactor
BigIntbenches against Python and Rust by @forfudan in #252 - [integer] Polish and simplify the
from_integral_scalar()method of BigInt by @forfudan in #253 - [integer][decimal] Implement
factorial()forBigIntandBigDecimalby @forfudan in #254 - [integer][decimal] Use binary splitting for
factorial()+ addpermutation()by @forfudan in #255 - [integer] Add
multiply_by_word_inplace()and use it forproduct_range()by @forfudan in #256 - [mojo][core] Update the codebase to mojo v1.0.0b2 by @forfudan in #257
- [doc] Update documents for release by @forfudan in #258
Full Changelog: v0.10.0...v0.11.0