Very large ID in JSON, how to get it without loss of precision
I have IDs in a JSON file and some of them are really big, but they fit within the unsigned long long int framework.
"id":9223372036854775807,
How do I get this large amount from JSON using objectForKey:idKey
from NSDictionary? Can NSDecimalNumber be used? Some of these identifiers fit into a regular integer.
source to share
Tricky. Apple JSON code converts integers above 10 ^ 18 to NSDecimalNumber and smaller integers to regular NSNumber containing a 64-bit integer value. Now, you might have hoped that unsignedLongLongValue would give you a 64 bit value, but that is not for NSDecimalNumber: NSDecimalNumber is converted to double first, and the result to unsigned is long, so you lose precision.
Here's something you can add as an extension to NSNumber. It's a little tricky because if you get a value very close to 2 ^ 64, converting it to double can be rounded to 2 ^ 64, which is not possible to convert to 64 bits. Therefore, we need to divide by 10 first to make sure the result is not too large.
- (uint64_t)unsigned64bitValue
{
if ([self isKindOfClass:[NSDecimalNumber class]])
{
NSDecimalNumber* asDecimal = (NSDecimalNumber *) self;
uint64_t tmp = (uint64_t) (asDecimal.doubleValue / 10.0);
NSDecimalNumber* tmp1 = [[NSDecimalNumber alloc] initWithUnsignedLongLong:tmp];
NSDecimalNumber* tmp2 = [tmp1 decimalNumberByMultiplyingByPowerOf10: 1];
NSDecimalNumber* remainder = [asDecimal decimalNumberBySubtracting:tmp2];
return (tmp * 10) + remainder.unsignedLongLongValue;
}
else
{
return self.unsignedLongLongValue;
}
}
source to share
Or process the raw JSON string, search for "id" = number; ". With the often included space, you can find the number and then write it at the specified number. You can put the data in a mutable data object and get a char pointer to overwrite.
[introduced with the iPhone so a bit concise]
source to share