swiftlang / swift-corelibs-foundation

The Foundation Project, providing core utilities, internationalization, and OS independence
swift.org
Apache License 2.0
5.29k stars 1.13k forks source link

[SR-5353] NSDecimalNumber cast to Int64 fails on some large numbers #4284

Open swift-ci opened 7 years ago

swift-ci commented 7 years ago
Previous ID SR-5353
Radar None
Original Reporter vlas (JIRA User)
Type Bug

Attachment: Download

Environment Apple Swift version 4.0 (swiftlang-900.0.45.6 clang-900.0.26) Apple Swift version 4.0-dev (LLVM 1a69f372ee, Clang 17f727b492, Swift a8ba0772cd)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler, Standard Library | |Labels | Bug, Foundation | |Assignee | None | |Priority | Medium | md5: 9c092cf213be7d5b64c0a4aaa961ffeb

Issue Description:

Attempting to conditionally cast some numbers larger than `90071992547409930` (`0x0C7FFFFFFFFFDFB2`) stored in `NSDecimalNumber` to `Int64` using `as?` fails (results in `nil`). Experimentally, all such numbers are multiples of 10, but not every multiple of 10 fails – only some of them, e.g.:

To exercise the issue, simply create a decimal number and cast it to Int64: `NSDecimalNumber(value: largeNumber) as? Int64`. Note that this issue does not occur if a normal `NSNumber` is used instead. This is a regression from Swift 3 where such numbers would be cast correctly.

An example where this behaviour would cause problems is decoding JSON using `JSONSerialization` on macOS 10.13 and iOS 11 where (some?) numbers are decoded internally into `NSDecimalNumber`. In cases where a cast to Int or Int64 during decoding would previously succeed, it would now fail.

Attached is a sample macOS command line project that demonstrates the issue.

belkadan commented 7 years ago

@phausler, is this a Swift issue, or would Objective-C Foundation have this behavior as well? (I suppose the "cast to Int64" is Swift-specific, but…)

be0aadd9-8960-4c13-b27b-3298be9f43c2 commented 4 years ago

Expected behaviour. Downcasting is not the same as type conversion.