Releases: ericmj/decimal
Releases · ericmj/decimal
v3.1.0
Enhancements
Decimal.new/2now accepts an optionaloptskeyword list and
forwards it toDecimal.parse/2, allowing callers to override
:max_digitsand:max_exponentwhen constructing a decimal from
a string.
Bug fixes
- Fix infinite loop in
Decimal.to_integer/1when the coefficient is
zero and the exponent is negative (e.g.Decimal.new("0.0")). Such
values now correctly convert to the integer0.
v2.4.1
v3.0.0
Note on the new defaults
The new decimal128 defaults are more than sufficient for currency and
other real-world numeric use cases. With precision: 34 and a scale of
2 (two digits after the decimal point for cents), values from 0.00 up
to roughly 99_999_999_999_999_999_999_999_999_999_999.99 (~10³², 100
nonillion) round-trip without rounding. Most upgrades from 2.x require
no code changes.
Security
- Make the v2.4.0 mitigations for CVE-2026-32686 the default. The
defaultDecimal.Contextand the public parse, cast, and to_string
functions now follow IEEE 754 decimal128 limits, rejecting inputs
such as1e1000000000without materializing them.
Breaking changes
Decimal.Contextdefaults change from precision28and unbounded
emax/eminto decimal128 values:precision: 34,emax: 6_144,
emin: -6_143. Operation results whose adjusted exponent leaves that
band signal overflow or underflow.Decimal.parse/1andDecimal.cast/1reject inputs whose digit count
exceeds34(decimal128 precision) or whose absolute exponent exceeds
6_144(decimal128 emax). Useparse/2/cast/2with
max_digits: :infinityandmax_exponent: :infinityto restore
unbounded behavior.Decimal.parse/2andDecimal.cast/2default:max_digitsto34
and:max_exponentto6_144when not specified.Decimal.to_string/2andDecimal.to_string/3raiseArgumentError
when the rendered output would exceed6_178digit characters
(precision + emax — the worst-case:normalwidth of any in-range
decimal128 value).Inspect,String.Chars, andJSON.Encoder
protocol implementations passmax_digits: :infinityso debug output
always succeeds.
v2.4.0
Security
- Mitigate exponent amplification (CVE-2026-32686).
Compact inputs such as1e1000000could force multi-second expansions
during arithmetic, parsing, normalization, comparison, or formatting.
Decimal.add/2andDecimal.sub/2now scale operands toprecision + 2
digits with a sticky bit instead of materializing the full coefficient.
Enhancements
- Add
:max_digitsand:max_exponentoptions toDecimal.parse/2and
Decimal.cast/2to reject pathological inputs without expansion - Add
:max_digitsoption toDecimal.to_string/3to cap formatted output
before materialization - Add
:emaxand:eminfields toDecimal.Contextfor IBM General Decimal
Arithmetic-style overflow and underflow signaling - Optimize hot paths for large decimals:
coef_length,normalize,
to_integer,integer?, parsing, and large-coefficient string formatting
v2.3.0
- Implement the upcoming
JSON.Encoderprotocol
v2.2.0
v2.1.1
v2.1.0
Decimal v2.1 requires Elixir v1.8+.
Enhancements
- Improve error message from
Decimal.to_integer/1during precision loss Inspectprotocol implementation returns strings in theDecimal.new(...)format- Add
Decimal.scale/1 - Optimize
Decimal.compare/2for numbers with large exponents
Bug fixes
- Fix
Decimal.integer?/1spec - Fix
Decimal.integer?/1check on 0 with >1 significant digits
v2.0.0
Decimal v2.0 requires Elixir v1.2+.
Enhancements
- Add
Decimal.integer?/1
Breaking changes
- Change
Decimal.compare/2to return:lt | :eq | :gt - Change
Decimal.cast/1to return{:ok, t} | :error - Change
Decimal.parse/1to return{t, binary} | :error - Remove
:messageand:resultfields fromDecimal.Error - Remove sNaN
- Rename qNaN to NaN
- Remove deprecated support for floats in
Decimal.new/1 - Remove deprecated
Decimal.minus/1 - Remove deprecated
Decimal.plus/1 - Remove deprecated
Decimal.reduce/1 - Remove deprecated
Decimal.with_context/2,Decimal.get_context/1,Decimal.set_context/1,
andDecimal.update_context/1 - Remove deprecated
Decimal.decimal?/1
v1.9.0
Enhancements
- Add
Decimal.negate/1 - Add
Decimal.apply_context/1 - Add
Decimal.normalize/1 - Add
Decimal.Context.with/2,Decimal.Context.get/1,Decimal.Context.set/2,
andDecimal.Context.update/1 - Add
Decimal.is_decimal/1
Deprecations
- Deprecate
Decimal.minus/1in favour of the newDecimal.negate/1 - Deprecate
Decimal.plus/1in favour of the newDecimal.apply_context/1 - Deprecate
Decimal.reduce/1in favour of the newDecimal.normalize/1 - Deprecate
Decimal.with_context/2,Decimal.get_context/1,Decimal.set_context/2,
andDecimal.update_context/1in favour of new functions on theDecimal.Contextmodule - Deprecate
Decimal.decimal?/1in favour of the newDecimal.is_decimal/1