Open wadetregaskis opened 1 year ago
import BigInt
extension Foundation.FormatStyle where Self == IntegerFormatStyle<BigUInt> {
static var number: IntegerFormatStyle<BigUInt> {
IntegerFormatStyle<BigUInt>()
}
}
var hmm: BigUInt = 9_223_372_036_854_775_807
while true {
let formatted = hmm.formatted(.number.locale(Locale(identifier: "en_US_POSIX")))
if BigUInt(formatted) != hmm {
print("Broke at \(hmm.description) - \(formatted).")
break
}
hmm += 1
}
Note that in the above example I added a number
static member to FormatStyle
for convenience (as the built-in overloads of number
are only for the Swift built-in numeric types), but that's not germane to the problem. If you delete that extension you can't use .number
anymore, but can still see the problem with other standard format style conveniences e.g. hmm.formatted(.currency(code: "usd"))
.
Also, IntegerFormatStyle
breaks with UInt64 at the same point. So this looks like a bug in the Swift standard library, in which case this GitHub issue is more of an FYI, I suppose. Maybe there's some way to work around the issue, e.g. provide a FormatStyle
implementation specifically for BigInt
/ BigUInt
?
description
(perCustomStringConvertible
) seems to work fine, but of course doesn't produce localised outputs (as expected per its purpose). I want localised outputs, which is normally (for the built-in numeric types) done via theformatted(…)
methods. These do exist onBigInt
andBigUInt
, but produce erroneous results at 2^63 and higher (9,223,372,036,854,775,808).e.g. 2^63 renders as "9,223,372,036,854,775,807" (which is 2^63 - 1, which happens to be
Int64.max
). e.g. 1e25 renders as "9,999,999,999,999,999,000,000,000".It appears the formatting's precision is somehow limited to the first (highest-order)
Int64
word, even though it does show the correct magnitude ("rounding" errors notwithstanding).