OK team, this is weird. [NSDecimalNumber integerValue] is behaving strangely.
I'm sat at a breakpoint, trying to figure out why some parts of my app are broken in iOS8, and I'm looking at a variable called "timeSeconds". It appears like this in the Xcode Variables View:
_timeSeconds (NSDecimalNumber *) 344.514533996581994496
But when I query it in the debugger, I see this:
(lldb) p [self.timeSeconds doubleValue]
(double) $14 = 344.51453399658192
(lldb) p [self.timeSeconds intValue]
(int) $15 = 344
(lldb) p [self.timeSeconds integerValue]
(NSInteger) $16 = -5
(lldb) p (NSInteger)[self.timeSeconds intValue]
(NSInteger) $17 = 344
See that "-5"? Can any of you beautiful people reproduce or explain that, before I file a radar?
Here's the SSCCE:
NSDecimalNumber *n = [NSDecimalNumber decimalNumberWithString:@"344.514533996581994496"];
NSLog(@"%@", n); // 344.514533996581994496
NSLog(@"%ld", (long)[n intValue]); // 344
NSLog(@"%ld", (long)[n integerValue]); // -5
NSLog(@"%ld", (long)[n unsignedIntegerValue]); // 12
Thanks in advance!
Matthew
The result for integerValue is surprising, but from what I understand as documented:
NSDecimalNumber inherits from NSNumber. In the subclassing notes from NSNumber it is stated that "... subclass must override the accessor method that corresponds to the declared type—for example, if your implementation of objCType returns “i”, you must override intValue ..."
objCType is set to the inner pointer, so it should be the same as for NSNumber.
NSDecimal does not override intergerValue. It does override doubleValue, so that should work fine.
The only thing that makes me wonder: it seems it does not override intValue either ...
What a great bug! I just found myself tricked by it. So, just to conclude dogsgods answer:
Do NOT:
NSInteger x = [myDecimalNumber integerValue];
Instead, do THIS:
NSInteger x = (NSInteger)[myDecimalNumber doubleValue];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With