Swiftpack.co -  davdroman/PreciseDecimal as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
davdroman/PreciseDecimal
Precise JSON decimal parsing for Swift 🧮
.package(url: "https://github.com/davdroman/PreciseDecimal.git", from: "1.0.0")

PreciseDecimal

CI status

Introduction

Swift has long suffered a problem with its Decimal type: unapparent loss of precision.

This happens with all common ways of initializing:

let badDecimal = Decimal(3.133) // 3.132999999999999488
let badDecimal: Decimal = 3.133 // 3.132999999999999488

But not these ones:

let goodDecimal = Decimal(string: "3.133") // 3.133
let goodDecimal = Decimal(sign: .plus, exponent: -3, significand: 3133) // 3.133

Furthermore, this also applies to JSON decoding since it uses NSJSONSerialization under the hood, which is presumed to parse decimal numbers as Double and then initializing a Decimal via its lossy Double initializer as exemplified above. A common workaround for this is to receive sensitive Decimal values as strings and parsing into Decimal with the working string initializer, however oftentimes the format of a JSON payload is out of one's control.

This is something that Apple will most likely fix at some point. In the meantime, PreciseDecimal has your back.

Usage

This library declares a lightweight PreciseDecimal type as a wrapper around Decimal, with precise init and Decodable implementations.

let goodDecimal = PreciseDecimal(3.133) // 3.133
let goodDecimal: PreciseDecimal = 3.133 // 3.133
struct Price: Decodable {
    let amount: PreciseDecimal
}

let json = #"{ "amount": 3.133 }"#.data(using: .utf8)!
let goodDecimal = try JSONDecoder().decode(Price.self, from: json).amount // 3.133

Try it out!

PreciseDecimal supports Arena to effortlessly take it for a spin in a playground before you decide to add it to your codebase.

Simply install Arena and run arena davdroman/PreciseDecimal --platform macos in your terminal.

FAQ

Why isn't it also a @propertyWrapper?

Decimals are often relied upon to accurately represent monetary values in financial applications. Given this delicate use case, I decided the most responsible way to expose this API is as a first-class struct only, to be used wherever a Decimal type may be declared. This strict way of offering the library ensures no loss of precision leaks through one's codebase by otherwise forgetting to annotate a Decimal property with @PreciseDecimal.

Why doesn't it have [insert here] feature?

In order to keep the library's scope and implementation as lightweight as possible, optimistic for a painless obsolescence once Apple fixes Decimal.

Do feel free to suggest otherwise if I missed a vital part of functionality that should definitely be in this library.

GitHub

link
Stars: 12
Last commit: 5 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Release Notes

1.0.0
5 weeks ago

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API