NSDecimalNumber возвращает неправильное значение uint64_t

Мое приложение запоминает MPMediaItems по persistentId, как и каждый. Он сохраняет persistentId в файле JSON, который затем читается и анализируется. NSJSONSerialization создает NSDecimalNumber для хранения идентификатора, который мое приложение позже использует в MPMediaQuery для получения MPMediaItem.

Я обнаружил, что иногда встречается неправильный MPMediaItem. Когда я еще немного покопался, я обнаружил, что когда я конвертирую NSDecimalNumber в значение uint64_t, [NSNumber unsignedLongLongValue] возвращает неправильное значение!

NSDecimalNumber* const songId = _songId;
uint64_t         const songIdValue = songId.unsignedLongLongValue;

songId is      1457249251113381177
songIdValue is 1457249251113381120
-or-
songId is      0x1439307919d12d39
songIdValue is 0x1439307919d12d00

Какого черта? Похоже, что младший байт очищается при преобразовании этого NSDecimalNumber в uint64_t. Это как-то правильное поведение для NSDecimalNumber я нашел ошибку в нем?

Я работаю над этим путем преобразования NSDecimalNumber из NSJSONSerialization в строку и преобразования строки в uint64_t с помощью [NSString longLongValue].

Это страшно, потому что кажется, что я теперь должен пойти и проверить КАЖДОЕ место, где я храню большие целые числа в файлах JSON и убедиться, что я оцениваю их таким NSString-y способом.

1 ответ

Если вы хотите сохранить максимальную точность, вы можете:

Работать только с NSDecimalNumbers,

Используйте NSString при передаче значения NSDecimalNumber в другую переменную, которая не является NSDecimalNumber. Такие методы, как [NSDecimalNumber longLongValue] или [NSDecimalNumber doubleValue] недостаточно конкретны.

NSDecimalNumber     *songId;
uint64_t            songIdValue;
NSString            *intermediateStr;

songId = [NSDecimalNumber decimalNumberWithString:@"1457249251113381177"];  
intermediateStr = songId.stringValue;
songIdValue = intermediateStr.longLongValue;

Почему использование строк является более точным, чем другие методы? Я не знаю. Но songIdValue содержит правильное значение без каких-либо потерь.

Другие вопросы по тегам