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

这不是我输入的内容。为清楚起见,如果我将其带回Double

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

所以 308 的震级减少到只有 52!这里发生了什么?我以为Decimal可以存储非常大的值,但似乎它甚至无法存储什么Double罐头!


短片:Double(exactly: Decimal(1.7976931348623e+308) as NSNumber)!

4

1 回答 1

1

这里发生了什么?

对我来说,这似乎是 Swift 标准库的一个错误。

它在 的文档中Decimal没有明确描述,但是Decimal(在 Objective-C 中,它是NSDecimal)是 的基础,NSDecimalNumber文档明确指出:

实例可以表示可以表示为尾数 x 10^exponent 的任何数字,其中尾数是最多 38 位长的十进制整数,指数是从 –128 到 127 的整数

(添加了粗体样式。)

因此,您highDouble不能表示为Decimal. 在我看来,Decimal.init(_: Double)应该是一个可失败的初始化程序,或者至少它应该Decimal.nan为不能表示为的数字返回(或一些适当的非数字值,如果有的话)Decimal

发生这种行为是因为当前实现Decimal.init(_: Double)将计算的小数设置exponent为内部_exponent而不检查其边界。您会发现Decimal(1e256)返回1.0000000000000008192(it's 1.0000000000000008192e0) 和52is 308-256

最好向Appleswift.org发送错误报告。


为什么 Decimal 不支持高 Doubles?

我认为 Decimal 可以存储非常大的值,但似乎它甚至无法存储 Double 可以存储的值!

如果这是您主要关心的问题,则在 Code Different 的评论中进行了描述。

于 2017-08-09T07:35:18.967 回答