2017-08-08 66 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'來存儲非常大的數字,當你需要精確的十進制浮點數時,你可以使用'Decimal',就像在財務計算中一樣。當需要大量數字時,請使用「bignum」等外部庫 –

回答

1

這是怎麼回事嗎?

對我來說,它似乎是一個Swift標準庫的bug。

它沒有清楚地在documentation of Decimal說明,但Decimal(在Objective-C,它的NSDecimal)是NSDecimalNumber基礎和its documentation明確規定:

實例可以表示可以表示任何數量的作爲尾數 ×10^exponent其中尾數是最多38位的十進制整數 長,而指數是從-128到127的整數

(粗體字加。)

所以,你highDouble不能表示爲Decimal。在我看來,Decimal.init(_: Double)應該是一個可分解的初始化程序,或者至少它應該返回Decimal.nan(或某個適當的非數字值,如果有的話)的數字不能表示爲Decimal

發生此問題的原因是current implementation of Decimal.init(_: Double)將計算得到的十進制exponent設置爲內部_exponent而未檢查其邊界。您可以找到Decimal(1e256)返回1.0000000000000008192(它是1.0000000000000008192e0),並且52308-256

最好發送一條錯誤報告給Appleswift.org


爲什麼小數不支持高雙打?

我認爲Decimal可以存儲非常大的值,但它似乎甚至不能存儲什麼Double可以!

如果這是您主要關心的問題,則在Code Different的評論中對此進行了描述。

+0

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