iPhone - Хранение двойного значения в NSDictionary только с 7 десятичными числами в виде числового типа - PullRequest
0 голосов
/ 25 сентября 2011

У меня есть PList, который содержит словарь с некоторыми десятичными значениями, такими как 10.1234567, который хранится как числовой тип (тег).
В моем приложении я читаю этот plist и манипулирую этими значениями как NSNumber (значения двойного типа) с помощьюПользовательский класс и его методы доступа:

@interface
...
@property(nonatomic, assign) NSNumber* someValue;
...
@end

@implementation
...
- (NSNumber*) someValue { return [self.dict objectForKey:@"val"]; }
- (void) setSomeValue:(NSNumber*)val { [self.dict setValue:val forKey:@"val"]; }
...
@end

Затем в некоторых случаях я записываю обратно на диск plist.

Несколько часов назад я заметил, что эти значения, скажем, преобразованы и теперь представляют собой что-то вроде 10.123456699999999.Все они !...

Вау, я не ожидал этого изменения.

Ну, я пытался решить проблему, связанную с изменением методов доступа, например: 1011 *

- (NSNumber*) someValue { return [self.dict objectForKey:@"val"]; }
- (void) setSomeValue:(NSNumber*)val { [self.dict setValue:
                                              [NSNumber numberWithDouble:[[NSString stringWithFormat:@"%.7lf", [val doubleValue]] doubleValue]] 
                                                          forKey:@"val"]; }

Но я не могу сохранить эти значения, оставив ихоригинальные 7 десятичных знаков.

Как мне сделать, чтобы записать только 7 десятичных знаков, не используя в словаре что-то кроме числового типа для поля (я имею в виду, использование String не было бы хорошим решением)?

Создание файла plist было сделано вручную, с несколькими часами ввода, вводя эти 7 десятичных значений в каждое поле, и они не были "преобразованы" в тот момент.Они были сохранены с 7 десятичными.Поэтому я думаю, что есть решение сохранить эти 7 десятичных знаков при записи их обратно программой.

Ответы [ 3 ]

1 голос
/ 25 сентября 2011

Возможно, вы захотите изучить стандарт IEEE 754-2008 и освежить в памяти свой двоичный файл. Компьютеры не хранят числа с плавающей запятой внутри, используя цифры от 10 до 9; скорее, они используют двоичные числа 0 и 1. Если вы введете 10.1234567 в компьютер и попросите его сохранить это число как 64-разрядное двойное число с плавающей запятой, самое близкое значение, которое он может получить к этому значению, будет что-то вроде 10.1234566999999. ... что ты видишь. И это число на самом деле что-то вроде 1001.00111111001101011011011 (т. Е. 10 + 2071259/16777216).

Если вы хотите сохранить точно 7 десятичных цифр, то сохраните необработанные символы в виде строки. Или придумайте какой-нибудь другой способ хранения цифр base-10 вместо двоичных цифр base-2.

Если вы хотите преобразовать число с плавающей запятой в текст с точностью до 7 цифр, вы можете использовать:

NSString* output = [NSString stringWithFormat:@"%.7d",myFloat];
1 голос
/ 25 сентября 2011

Добро пожаловать в удивительный мир с плавающей точкой.Если вы хотите использовать значения с плавающей запятой, вы должны быть готовы к тому, что значения с плавающей запятой лишь в редких случаях являются именно теми значениями, которые вы хотите, но чаще всего более или менее.

Вы можете использоватьцелое число (масштабируется по мере необходимости) или преобразовывается в символьную форму.Существует класс NSDecimalNumber, который был бы точным, но он не вписывается в схему NSNumber и, насколько мне известно, не будет работать с JSON и др., Если это будет необходимо.Должен, однако, работать как ключ словаря.

0 голосов
/ 25 сентября 2011

Используйте NSNumberFormatter, когда вы извлекаете NSNumber из списка, и он должен работать:

NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
[nf setMaximumFractionDigits:7];
NSNumber *yourNumber = [nf numberFromString:[[self someValue] stringValue]];
...