JSONSerialization rounding large decimal number

Number:rdar://33287132 Date Originated:July 13 2017, 12:06 PM
Status:Open Resolved:
Product:iOS + SDK Product Version:11 beta3
Classification:Bug Reproducible:Always

It seems that JSONSerialization behaves differenly on iOS 11 and large decimal numbers (i.e Decimal.MaxValue (C#), which is 79228162514264337593543950335) is rounded up, because its internal representation was changed from NSDecimalNumberPlaceholder to NSNumber.

After retrieving this value, the result is rounded to 79228162514264340000000000000, while on iOS it has still correct value: 79228162514264337593543950335.

Is this behavior expected? The problem is that we cannot send back a rounded number to our backend because it is larger than Decimal.MaxValue. The workaround is to pass decimals as strings in JSON, but this will require a significant change on both backend and client.

Steps to Reproduce:
let str = "{ \"data\": 79228162514264337593543950335 }" // C# Decimal.MaxValue
let data = str.data(using: .utf8)
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
let dict = json as? [String: AnyObject]
let val = dict!["data"] //7.922816251426434e+28
print(val!.classForCoder) //NSNumber.Type (on iOS 10 we have here another internal type which is NSDecimalNumberPlaceholder)

let decimal = NSDecimalNumber(string: val?.stringValue) //
decimal.stringValue // 79228162514264340000000000000 should be 79228162514264337593543950335

Expected Results:

Observed Results:

iOS 11 b2 and b3 (Xcode 9b2 and 9b3)

Affects both project written in Swift and Objective-C



Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!