2017-08-08 8 views
0
let highDouble = 1.7976931348623e+308 // Just under Double.greatestFiniteMagnitude 
print(highDouble) // 1.7976931348623e+308 
let highDecimal = Decimal(highDouble) 
print(highDecimal) // 17976931348623005696000000000000000000000000000000000 

これは私が入れものではありません、私はその裏Doubleに持ち込む場合は明確にするために、:。Decimalは高倍率をサポートしていないのはなぜですか?

let newHighDouble = Double(exactly: highDecimal as NSNumber)! 
print(newHighDouble) // 1.7976931348623e+52 

だから、308の大きさのみが52に減少しました! ここには何が起こっていますか?私はDecimalが非常に大きな値を格納することができると思ったが、それも何Double缶を保存することができないようだ


ショートスニペットは:Double(exactly: Decimal(1.7976931348623e+308) as NSNumber)!

+0

精度とスケールの関係です。ここでは[.NETの議論](https://stackoverflow.com/questions/618535/difference-between-decimal-float-and-double-in-net)ですが、Swiftにも適用されます。あなたは非常に大きな数値を格納するために 'Decimal'を使用しません。財務計算のように正確な10進浮動小数点数が必要なときは' Decimal'を使います。巨大な数字が必要な場合は、「bignum」のような外部ライブラリを使用してください。 –

答えて

1

はここで何が起こっているの?

私にとっては、Swift Standard Libraryのバグのようです。

これは明らかdocumentation of Decimalに記載されていないが、Decimalは(Objective-Cで、それはNSDecimal'S)NSDecimalNumberits documentationの根拠が明確に述べている:インスタンスを

を発現させることができる任意の数を表すことができ仮数として仮数は38桁の長 、及び指数までの10進整数である ×10 ^指数は127介して-128の整数です。

(太字スタイルが追加されます。)

をだから、あなたのhighDoubleDecimalとして表現することはできません。私の意見では、Decimal.init(_: Double)はfailable初期化子であるべき、あるいは少なくともそれはDecimalとして表すことができない数字のために(もしあれば、あるいはいくつかの適切な非数値)Decimal.nanを返す必要があります。

current implementation of Decimal.init(_: Double)は、exponentの計算済みの小数点を、その範囲をチェックせずに_exponentに設定しているために発生します。あなたはDecimal(1e256)戻り1.0000000000000008192(それは1.0000000000000008192e0だ)、および52308-256であることを見つけることができます。

良いAppleまたはswift.orgにバグレポートを送信します。


なぜ10進高いダブルスをサポートしていませんか?

私はDecimalが非常に大きな値を格納できると思っていましたが、Doubleが何を保存することさえできないようです。これはあなたの主な関心事である場合

は、それが異なるコードのコメントで説明しています。

+0

[SR-5678](https://bugs.swift.org/browse/SR-5678) –

関連する問題