It appears there's no way to render a UInt64 (or similarly large integer type) to a localised string (appropriate thousands separators etc) in the Swift standard library nor Foundation?
The FormatStyle stuff (.formatted(…) etc) is broken for numbers above Int64.max (FB13170519):
let value = UInt64(Int64.max) + 1 // 9223372036854775808
value.formatted(.number) // "9223372036854775807"
value.description // "9223372036854775808"
So, as a workaround, is there a good 3rd party package for this, ideally fully supporting all BinaryIntegers (as I'm most interested in doing this for a BigInt implementation, not UInt64 specifically)?
I'm not sure why, but I think this may be what's happening:
The .formatted(_:) method calls a cached NumberFormatter instance, which means that the UInt64 is casted to an NSNumber internally. NSNumber is toll-free bridged with CFNumber, which is basically this:
enum CFNumber {
case floating(Double)
case integer(Int64)
}
So the conversion to NSCFNumber is probably truncating the number to fit into Int64.
Yeah, but not for arbitrary-precision integers, which is my actual use case. I was just more surprised to find that it's broken for two of the most fundamental integer types in Swift (UInt and UInt64) [than third-party bigint libraries].
Curiously of all the BigInt packages I've reviewed so far - and there are a surprisingly large number in Swift - not a single one supports localised string rendering.
I'm curious if the new [new] Foundation will fix / has fixed this. Alas I have no idea how to utilise it in my app (SwiftUI Mac app) even for exploratory purposes, let-alone to ship (I assume we have to wait some number of years - but hopefully not never - for the new [new] Foundation to actually be integrated into the OSes?).