【问题标题】:NSNumberFormatter.string(from: ) maximum possible Value exceeded does not result in Overflow - SwiftNSNumberFormatter.string(from: ) 超出的最大可能值不会导致溢出 - Swift
【发布时间】:2017-06-22 02:45:48
【问题描述】:

我正在将数字转换为纯英文单词,遇到了一些很奇怪的情况:NSNumberFormatter 有一个奇怪的输出,小于期望的结果,但是作为参数的数字不会导致溢出。

我有以下代码:

 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,相当于18014398509481984999999999999999999。如果我尝试从18014398509481984 获取单词,结果就是我所期望的,即上面描述的字符串。但是,如果我在999.. 中再添加一个9,它会崩溃并显示以下消息:

整数文字 9999999999999999999 在存储到 Int 时溢出

这里是Swift Sandbox Test,为了让问题更容易理解


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

【问题讨论】:

  • 奇怪。即使你使用180140398509481985,拼写出来时你仍然会得到180140398509481984
  • 这也是一个奇怪的限制。介于 2^57 和 2^58 之间。
  • @rmaddy 这正是我要问的。它只是对该函数的某种限制,还是 Int / NSNumber 最大值有问题?
  • 由于某种原因,我找不到那个数字的任何特殊属性,我不知道发生了什么
  • 这似乎是对spellOut 风格的NumberFormatter 的某种限制/错误。

标签: ios swift overflow nsnumberformatter


【解决方案1】:

9_999_999_999_999_999_999 导致Int 溢出,因为它大于Int64.max9_223_372_036_854_775_807(即0x7fffffffffffffff)。

关于为什么数字格式化程序在 18_014_398_509_481_984(即 2540x40000000000000)为 .spelledOut 封顶,这似乎有点像源自 64 位浮点表示的错误的价值。如果不详细了解NSNumberFormatterNSNumber 的来源,我们无法确定,但我建议这样做,因为巧合的是,这里的上限恰好是 64 位浮点类型的最大整数值的两倍可以忠实地捕捉。

【讨论】:

  • Foundation 和 Core Foundation 是开源的。 CFNumberFormatterCreateStringWithNumber 函数甚至有一个无所不在的警告,即“具有大的无符号 64 位整数的 CFNumbers 的值不能很好地通过这个”。看起来 Apple 已经知道这个问题了。
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2016-02-09
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
相关资源
最近更新 更多