swift-atoms/swift-decimal
Use this package when you need IEEE 754 decimal floating point: values such as money or measurements that must round in base ten and that need the standard rounding, flags and special values. The Decimal product holds the three interchange formats Decimal.Format32, `Decimal.F
Laws
- A value is its coefficient × 10^exponent.
Decimal.Exponentlimits such asmaxExponentandminExponentbound that quantum exponent.Decimal.Exponent.Format64.scientificMinand its siblings bound the adjusted exponent, which is the exponent of the leading digit. A finite nonzero value is.subnormalexactly when its adjusted exponent is belowscientificMin. ==andhash(into:)compare numeric values, not encodings. Members of one cohort (1 and 1.00) are equal and hash alike. Zeros are equal whatever their sign or exponent. NaN is unequal to everything, itself included. Infinities are equal only when their signs match. A coefficient abovecoefficientMax()counts as zero.<andDecimal.Operation.comparefollow IEEE comparison: NaN is.unorderedand −0 equals +0.Decimal.Operation.orderis the IEEE total order instead: −NaN < −sNaN < −∞ < finite < +∞ < +sNaN < +NaN, −0 precedes +0, and NaNs of the same kind and sign are ordered by payload.- Every operation rounds once, to the precision and rounding of its
Decimal.Context.fusecomputesself × a + bexactly and rounds only the final sum. The operators, integer literals andSwift.FloatingPointrequirements use the format's default context (Decimal.Context.format64and its siblings: round half to even, no traps) and discard the status. Decimal.Context.trapstakes effect only through thetrapping:overloads. Each of these throws oneDecimal.Trapfor the first raised flag inDecimal.Flag.allCasesorder (invalid, divide, overflow, underflow, inexact). The trap carries the full status and the value that would have been returned. The non-throwing overloads never trap.- When an operand is a signaling NaN, the result is a quiet NaN that carries the first signaling operand's coefficient as its payload, and
.invalidis raised. Otherwise the first quiet NaN operand is returned unchanged, with no flag. - These operations return NaN with
.invalid: ∞ − ∞, 0 × ∞, 0 ÷ 0 and ∞ ÷ ∞, and infusean infinite product added to an infinity of the opposite sign. Dividing a nonzero finite value by zero returns a signed infinity with.divide. - An exact zero sum is +0, unless both operands are −0 or the rounding is
.down. Then it is −0. - An integer literal rounds half to even when it has more digits than the format's precision. So does
init(_:)taking anIntor a genericBinaryInteger, and an integer that exceeds the exponent range becomes infinity.init?(exactly:)returns nil instead of rounding. EveryInt64literal is exact inDecimal.Format128. Decimal.Text.Parseaccepts an optional sign, digits with at most one., and an optionalE/eexponent. It also acceptsInf,Infinityand the text "NaN" in any letter case, with an optional sign. Leading zeros do not count toward precision. A coefficient with too many digits is rounded by the context and the parse does not report it as inexact. An exponent outside the context's range throws instead of producing infinity or zero.- Rendering writes the text "NaN" and
Infinitywith their sign, but a NaN's payload and its signaling kind are dropped. Any zero renders as0(or-0), whatever its exponent..plainnever uses exponent notation, so it writes every zero digit..scientificalways writes a signed exponent..engineeringwrites an exponent that is a multiple of three, or none when that exponent is zero.render(into:)requires a buffer of at leastrequiredCapacity(style:)bytes.
Package Metadata
Repository: swift-atoms/swift-decimal
Default branch: main
README: README.md