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
9999999999999999999
overflows 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