2017-02-04 9 views
5

数値を純粋な英語の単語に変換しています。私は非常に奇妙な状況に遭遇しました。NSNumberFormatterは、パラメータとして取られた数はオーバーフローを引き起こさない。NSNumberFormatter.string(from:)最大値を超えてもオーバーフローが発生しません - スウィフト

Iは、次のコードを有する:

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

が、これは18014398509481984 < 999999999999999999のと等価であるeighteen quadrillion fourteen trillion three hundred ninety-eight billion five hundred nine million four hundred eighty-one thousand nine hundred eighty-fourを印刷します。 18014398509481984から単語を取得しようとすると、上記の文字列が返されます。 質問より多くを作るために、ここでInt

に保存されたとき

整数リテラル9999999999999999999オーバーフローSwift Sandbox Test次のとおりです。私は9999..への1以上を追加する場合は、それはメッセージでクラッシュわかりやすい。


私の実際の質問は:180140398509481984numberFormatter.string(from:)の制限のいくつかの種類である理由999999999999999999がオーバーフローを引き起こさないが、ちょうどその制限を表示し、9999999999999999999(と:は最初の試みの出力があると仮定すると余分な9)オーバーフローが発生しますか?

+1

奇妙な。あなたが '180140398509481985'を使っても、スペルアウトされても' 180140398509481984 'が得られます。 – rmaddy

+1

これも奇妙な制限です。それは2^57と2^58の間です。 – rmaddy

+0

@rmaddyこれはまさに私が求めていることです。この関数には何らかの制限がありますか、それともInt/NSNumberの最大値に問題がありますか? –

答えて

4

Int64.max9_223_372_036_854_775_807(即ち0x7fffffffffffffff)よりも大きいので9_999_999_999_999_999_999Intオーバーフローを引き起こします。疑わしい値の64ビット浮動小数点representions起因するバグのように思える数フォーマッタは.spelledOutため(すなわち、2 、0x4000000000000018_014_398_509_481_984で実施キャッピングされている理由について

、。 NSNumberFormatterNSNumberの情報源を一通り詳しく調べることはできませんが、ここで上の天井は偶然にも64ビットの浮動小数点型が忠実にキャプチャできる最大の整数値の2倍です。

+0

私は気付かなかった...ありがとう –

+1

基金とコア財団はオープンソースである。['CFNumberFormatterCreateStringWithNumber'](https://github.com/apple/swift-corelibs-foundation/blob/173e9ea16cf1a0ed9b21cc11ea8a2d15b3f8dca9/CoreFoundation/Locale.subproj/CFNumberFormatter.c)関数では、「CFNumberFormatterCreateStringWithNumber'の値は、大きな符号なし64ビットintはこれでうまく生き残れません "。 Appleはすでにこの問題について知っていたように見えます。 –

関連する問題