[0.41.0] — June 3rd, 2026
Breaking Changes
Localize.Number.Format.Compilernow rejects scientific patterns that contain a grouping separator (e.g."#,##0.###E0") at compile time. TR35 forbids grouping in scientific patterns; the comma was previously silently ignored at output time. Fix: drop the comma, or use a non-scientific pattern.
Enhancements
-
TR35 engineering notation. Patterns like
"##0.#####E0"now correctly shift the mantissa so the exponent is a multiple of the pattern's max integer-digit count:12345 → "12.345E3",123456 → "123.456E3". Fixed-width mantissa patterns ("00.###E0") similarly shift to exposemin_integer_digitsinteger digits. The shift is exact forDecimal(via the%Decimal{exp: …}field) and lossless forDecimal-promoted floats/integers. -
New
:engineeringformat atom resolving to"##0.######E0". CLDR ships no engineering pattern, so this is a Localize-supplied default — pass an explicit pattern string for different mantissa precision. -
Scientific-pattern emission now reads
options.symbols.exponential,options.symbols.minus_sign, andoptions.symbols.plus_signfrom the locale's CLDR data instead of hardcoding ASCII"E","+","-".ar/arabrenders"أس"with Arabic Letter Mark signs,fa/arabextrenders the"×۱۰^"superscripting form,ar/latnwraps signs with U+200E LRM. -
Localize.Number.Format.Compilernow normalises@-significant scientific patterns per TR35:"@@###E0"≡"0.0###E0","@@@##E0"≡"0.00##E0", etc. The compiler rewrites these to the canonical0-prefixed form so the runtime formatter does not need a separate@-aware path. -
New
:exponent_styleoption onLocalize.Number.to_string/2.:e(the default) emits the standard1.234E3form;:superscriptemits1.234 × 10³using CLDR'ssuperscriptingExponentsymbol and Unicode superscript digits (⁰¹²³⁴⁵⁶⁷⁸⁹⁻⁺). Ignored for non-scientific patterns.
Bug Fixes
-
Localize.Utils.Math.round_significant/2no longer crashes when called with aDecimalandn <= 0or with a Decimal zero of any sign. Previously these reached:math.log10/1deep in the Decimal square-root path and raised:invalid_operation; both cases now return the input unchanged. -
Localize.Number.Format.Compiler.compile/1propagates compile-time errors fromformat_to_metadata/1instead of crashing withMatchError.