This library provides:
Decimal64: Custom decimal number value type of 64-bit size. It supports up to 16 decimal digits of accuracy.DecimalFP64: IEEE 754 compliant decimal number value type of 64-bit size. It supports up to 16 decimal digits of accuracy.- Conversion to and from Swift number types to decimal numbers.
The decimal number types have no dependencies (not even Foundation) and work on any OS supporting Swift 5.1 or later.
-
Decimal64.Custom decimal number value type focused on speed. It conforms to
SignedNumeric,Strideable, but notFloatingPoint. It has no support for+/-Infinity and ignores NaNs.let pi: Decimal64 = .pi let multiplier: Decimal64 = 2.5 let bias = Decimal64(7, power: 3) // 7 * 10^3 let divisor: Decimal64 = "0.953" // Supports string-number conversion let resultA = pi * multiplier + bias / divisor let resultB = resultA >> 2 // Divide by 100 (i.e. 10^-2)
The decimal number uses an internal 64-bit composed of two values: significand and exponent. Decimal numbers use the formula
significand * 10 ^ exponent. The internal values use two's complement. -
DecimalFP64.Decimal number conforming to the
FloatingPointtrying to follow IEEE 754 as closely as possible and supports+/-Infinity, signed zeros, and NaNs.The decimal number uses an internal 64-bit composed of three values: exponent, sign, and significand. Decimal numbers use the formula
sign * significand * 10 ^ exponent.DecimalFP64is a work-in-progress and it still lacks some functionality. Don't use it in production code. -
Foundation's
Decimal.Reference decimal number type of 160-bit size. It is implemented in Objective-C which doesn't conform to
FloatingPoint. It is not very good for performant sensitive processing (overhead on retain/release and general processing). -
Swift's
Double.Value binary floating-point type with 64-bit backed by fast hardware support. As it is well known, binary floating points are unable to express certain decimal numbers.
This Swift package contains a small benchmarking command-line application. The benchmark measures the performance of a few basic operations (+, *, /, and string conversion) for the previously defined floating-point types: Decimal64, DecimalFP64, Decimal, and Double.
The results vary depending on the host machine and OS, but in the author's machine (compiling for release):
| Type | Duration (secs) |
|---|---|
Decimal64 |
1.026 |
DecimalFP64 |
1.087 |
Double |
1.381 |
Decimal |
5.137 |
Double (generic) |
1.823 |
DecimalFP64 (generic) |
1.786 |
Be sure to compile and run for release. It doesn't make sense to measure performance with debug configuration for several reasons:
- The Swift Standard Library and Foundation linked are already compiled for release.
- The provided decimal numbers heavily rely on inlineable functionality and Swift optimizations.
