3

I have IDs in JSON file and some of them are really big but they fit inside bounds of unsigned long long int.

"id":9223372036854775807,

How to get this large number from JSON using objectForKey:idKey of NSDictionary? Can I use NSDecimalNumber? Some of this IDs fit into regular integer.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Prettygeek
  • 2,461
  • 3
  • 22
  • 44

2 Answers2

3

Tricky. Apple's JSON code converts integers above 10^18 to NSDecimalNumber, and smaller integers to plain NSNumber containing a 64 bit integer value. Now you might have hoped that unsignedLongLongValue would give you a 64 bit value, but it doesn't for NSDecimalNumber: The NSDecimalNumber first gets converted to double, and the result to unsigned long long, so you lose precision.

Here's something that you can add as an extension to NSNumber. It's a bit tricky, because if you get a value very close to 2^64, converting it to double might get rounded to 2^64, which cannot be converted to 64 bit. So we need to divide by 10 first to make sure the result isn't too big.

- (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;
    }
}
gnasher729
  • 51,477
  • 5
  • 75
  • 98
0

Or process the raw JSON string, look for '"id" = number; '. With often included white space, you can find the number, then over write it with the number quoted. You can put the data into a mutable data object and get a char pointer to it, to overwrite.

[entered using iPhone so a bit terse]

David H
  • 40,852
  • 12
  • 92
  • 138