I am converting numbers to pure English words, and I ran into some very odd situations: NSNumberFormatter has a strange output, smaller than the desired result, but the number taken as parameter doesn't cause an overflow.
I have the following code:
import Foundation
var numberFormatter: NumberFormatter = NumberFormatter()
numberFormatter.numberStyle = .spellOut
var result: String?
result = numberFormatter.string(from: 999999999999999999)
print(result ?? "nil")
and this prints eighteen quadrillion fourteen trillion three hundred ninety-eight billion five hundred nine million four hundred eighty-one thousand nine hundred eighty-four, which is the equivalent of 18014398509481984< 999999999999999999. If I try to get the words from 18014398509481984, the result is the one I expected, the string described above. However, if I add one more 9 to 999.., it crashes with the message:
integer literal
9999999999999999999overflows when stored intoInt
Here is a Swift Sandbox Test, in order to make the question more understandable.
My actual question is: Assuming that the output of the first try: 180140398509481984 is some kind of limit for numberFormatter.string(from:), why does 999999999999999999 not result in Overflow, but just displays that limit, and 9999999999999999999 (with an extra 9) results in Overflow?
The 9_999_999_999_999_999_999 causes an Int overflow because it is larger than Int64.max is 9_223_372_036_854_775_807 (i.e. 0x7fffffffffffffff).
Regarding why number formatter is capping out at 18_014_398_509_481_984 (i.e., 254, 0x40000000000000) for .spelledOut, that seems suspiciously like a bug stemming from 64-bit floating point representions of the value. We can't be sure without going through the source for NSNumberFormatter and NSNumber in some detail, but I suggest this because the upper ceiling here is, coincidentally, precisely double the largest integer value that a 64-bit floating point type can capture faithfully.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With