Why does Decimal not support high Doubles?

271 views Asked by At
let highDouble = 1.7976931348623e+308 // Just under Double.greatestFiniteMagnitude
print(highDouble) // 1.7976931348623e+308
let highDecimal = Decimal(highDouble)
print(highDecimal) // 17976931348623005696000000000000000000000000000000000

This is not what I put in. For clarity, if I bring that back into a Double:

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

So a magnitude of 308 was reduced to only 52! What's going on here? I thought Decimal could store extraordinarily large values, but it seems it can't even store what a Double can!


Short snippet: Double(exactly: Decimal(1.7976931348623e+308) as NSNumber)!

1

There are 1 answers

0
OOPer On BEST ANSWER

What's going on here?

For me it seems to be a bug of Swift Standard Library.

It is not clearly described in the documentation of Decimal, but Decimal (in Objective-C, it's NSDecimal) is the basis of NSDecimalNumber and its documentation clearly states:

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.

(Bold style added.)

So, your highDouble cannot be represented as Decimal. In my opinion, Decimal.init(_: Double) should be a failable initializer, or at least it should return Decimal.nan (or some appropriate non-number value, if any) for numbers which cannot be represented as Decimal.

This behavior happens because current implementation of Decimal.init(_: Double) is setting the calculated decimal exponent to internal _exponent without checking its bounds. You can find that Decimal(1e256) returns 1.0000000000000008192 (it's 1.0000000000000008192e0), and 52 is 308-256.

Better send a bug report to Apple or swift.org.


Why does Decimal not support high Doubles?

I thought Decimal could store extraordinarily large values, but it seems it can't even store what a Double can!

If this is your main concern, it's described in the comment of Code Different.