为什么 Decimal 不支持高 Double?

Why does Decimal not support high Doubles?

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)!

这是怎么回事?

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

documentation of Decimal, but Decimal (in Objective-C, it's NSDecimal) is the basis of NSDecimalNumber and its documentation中没有明确说明,明确指出:

An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.

(添加了粗体。)

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

发生此行为是因为 current implementation of Decimal.init(_: Double) 将计算出的小数 exponent 设置为内部 _exponent 而未检查其边界。可以发现Decimal(1e256)returns1.0000000000000008192(就是1.0000000000000008192e0),而52就是308-256.

最好将错误报告发送至 Apple or swift.org


为什么Decimal不支持高Double?

我以为 Decimal 可以存储非常大的值,但似乎连 Double 都不能存储!

如果这是您主要关心的问题,请在代码不同的评论中进行描述。