NSDecimalNumber is not printed correctly by NSLog

Originator:nicked
Number:rdar://44916684 Date Originated:2018/10/1
Status:Open Resolved:
Product:iOS SDK Product Version:
Classification: Reproducible:Always
 
Area:
Foundation

Summary:
When you print a NSDecimalNumber to the console using NSLog, the number is converted to a double first, potentially resulting in floating point rounding errors. This does not happen if you convert the NSDecimalNumber to a string by any other method first.

Steps to Reproduce:
NSDecimalNumber *d = [NSDecimalNumber decimalNumberWithString:@"99.9"];
NSLog(@"%@", d);     //prints "99.90000000000001"
NSLog(@"%@", d.description);     //prints "99.9"
NSLog(@"%@", d.stringValue);     //prints "99.9"
NSLog(@"%@", [d descriptionWithLocale:nil]);     //prints "99.9"

Expected Results:
All of the NSLog calls should print "99.9" for this number.

Actual Results:
If the NSDecimalNumber is passed directly to NSLog, it is converted to a double somewhere.

It seems this is happening during the mapping to os_log. Inside _os_log_fmt_flatten_data, it tests if the object is an instance of NSNumber and then directly calls -objCType, which for this decimal number returns "d" (double). Then -doubleValue is called on the decimal number, which creates the rounding error.

Version/Build:
Xcode 9.2 (also the same on Xcode 10.0)

Comments


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!