I have a NSDictionary that contains a key with a value of 4937446359977427944. I try and get the value of it as a long long and get 4937446359977427968 back?
NSDecimalValue
is not stored as a double
, it's a 64 bits unsigned integer mantissa, an 8 bit signed integer exponent of base 10, and a sign bit.
The problem is that an exact value of an NSDecimalValue
is only representable as ... an NSDecimalValue
.
You can get an approximate 64 bits IEE754 value with method doubleValue
.
When you try to use longLongValue
you effectively get the result of casting to a long long int the approximate IEE754 value.
You may or may not consider it a bug in the implementation of NSDecimalValue
(and eventually file a radar and ask Apple to use a different conversion routine). But strictly speaking this is not a bug: it's a design decision.
You should think of NSDecimalValue
as a sort of floating point decimal. In fact it's very similar to a software implementation of what IEEE754 would call an extended precision floating point decimal number, except that it does not conform to that definition (because it does not have an exponent supporting at least values between −6143 and +6144 and because it does not support NANs and infinites).
In other words, it's not an extended implementation of an integer, it's an extended (but lacking NANs and infinites) implementation of a double. The fact that Apple natively only provides an approximate conversion to double
(implying that the conversion to long long int may or may not be exact for any value that exceed 53 bits of precision) is not a bug.
You may or may not want to implement a different conversion yourself (with a category).
Another possible point of view is to consider the problem being a bug in the JSon implementation you used. But this is also highly debatable: it gave you a NSDecimalValue
and that's arguably a correct representation. Either you operate with the NSDecimalValue
or you are responsible for any conversion of it.