2017-08-08 64 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) –