2017-02-04 127 views
5

我将数字转换为纯英文单词,并遇到一些非常奇怪的情况:NSNumberFormatter有一个奇怪的输出,比想要的结果小,但是作为参数的数字不会导致溢出。NSNumberFormatter.string(from:)最大可能的值超出不会导致溢出 - 斯威夫特

我有以下代码:

import Foundation 
var numberFormatter: NumberFormatter = NumberFormatter() 
numberFormatter.numberStyle = .spellOut 
var result: String? 
result = numberFormatter.string(from: 999999999999999999) 
print(result ?? "nil") 

和此打印eighteen quadrillion fourteen trillion three hundred ninety-eight billion five hundred nine million four hundred eighty-one thousand nine hundred eighty-four,这是18014398509481984 < 999999999999999999等效。如果我试图从18014398509481984获得单词,那么结果就是我期望的结果,即上面描述的字符串。不过,如果我添加一个9999..,它与消息崩溃:

整数文字9999999999999999999溢出时存入Int

这里是一个Swift Sandbox Test,为了使问题更可以理解的


我实际的问题是:假设第一次尝试的输出:180140398509481984是某种限制为numberFormatter.string(from:),为什么999999999999999999不会导致溢出,而​​只是显示极限,9999999999999999999(带额外9)导致溢出?

+1

奇怪。即使你使用'180140398509481985',拼写出来的时候你仍然会得到'180140398509481984'。 – rmaddy

+1

这也是一个奇怪的限制。它介于2^57和2^58之间。 – rmaddy

+0

@rmaddy这正是我所要求的。这是否仅限于某种功能,还是Int/NSNumber max值有问题? –

回答

4

9_999_999_999_999_999_999导致Int溢出,因为它比Int64.max越大9_223_372_036_854_775_807(即0x7fffffffffffffff)。

关于为什么数字格式化在18_014_398_509_481_984(即,2 54 0x40000000000000)为.spelledOut封盖出来,这似乎很像从值的64位浮点representions词干的错误。我们不能确定没有详细地通过NSNumberFormatterNSNumber的源代码,但我建议这样做,因为这里的上限恰好是64位浮点类型能够忠实捕获的最大整数值的两倍。

+0

我没有注意到...谢谢 –

+1

基金会和核心基金会是开源的。['CFNumberFormatterCreateStringWithNumber'](https://github.com/apple/swift-corelibs-foundation/blob/173e9ea16cf1a0e9b21cc11ea8a2d15b3f8dca9/CoreFoundation/Locale.subproj/CFNumberFormatter.c)函数甚至会有一个无所不在的警告,即“CFNumbers的值与大的无符号64位整数不能很好地通过这个“生存”。看起来苹果已经知道这个问题。 –