NSNumberFormatter округляется до отрицательного нуля

Я использую NSNumberFormatter для форматирования значений с плавающей запятой в виде целочисленных строк, т.е. опуская дробную часть. Мне кажется странным, что числа в диапазоне (-0.5, 0) *открытый интервал заканчиваются как -0. Поскольку это значение будет отображаться пользователю, я думаю, что отрицательный ноль не подходит. Я безуспешно экспериментировал с различными комбинациями numberStyle и roundingMode.

Есть ли способ настроить NSNumberFormatter для вывода их как 0, или мне нужно прибегнуть к ручной коррекции для этого диапазона?


person Palimondo    schedule 31.05.2012    source источник


Ответы (2)


Пришлось исправлять это самому. Я использую NSNumberFormatter для отображения температуры со значением по умолчанию numberStyleNSNumberFormatterNoStyle, которое округляет числа до целого числа, roundingMode устанавливается равным NSNumberFormatterRoundHalfUp. В конце концов я перехватил значения в проблемном диапазоне и сам округлил их:

- (NSString *)temperature:(NSNumber *)temperature
{
    float f = [temperature floatValue];
    if (f < 0 && f > -0.5)
        temperature = [NSNumber numberWithLong:lround(f)];

    return [self.temperatureFormatter stringFromNumber:temperature];
}
person Palimondo    schedule 18.07.2012
comment
Проблема в том, что вы исправляете это на вызывающем сайте, когда вы должны реализовать это локально в методе расширения средства форматирования чисел. Что-то вроде changeToZeroIfNegativeZero. Это похоже на метод расширения nilIfEmpty в классе String. - person Pavan; 04.05.2020

Нет, нет способа настроить его для этого.

В «режиме 10.4» NSNumberFormatter в основном просто обертывает CFNumberFormatter (хотя это не прямая бесплатная обертка с мостом). Вы можете взглянуть на список ключей свойств Number Formatter, и становится совершенно ясно, что нет ничего, что могло бы делать то, что вы хотите. (Возможно, это возможно в режиме «10.0»; потребуется немного проб и ошибок, чтобы выяснить это. Но я сомневаюсь, что вы захотите его использовать.)

Так что предварительное округление (как предлагает Джастин Бу), вероятно, ваш лучший вариант.

Вместо этого вы, конечно, можете использовать постобработку. То, что именно вы хотите сделать, вероятно, зависит от того, хотите ли вы отображать -0.00 как 0.00, что вы хотите сделать для локализаций, которые не используют «-0» и т. д. Самый простой случай будет таким же простым, как этот:

@interface NSNumberFormatter (NegativeZero)
- (NSString *)stringFromNumberNoNegativeZero:(NSNumber *)number;
@end

@implementation NSNumberFormatter (NegativeZero)
- (NSString *)stringFromNumberNoNegativeZero:(NSNumber *)number {
  NSString *s = [self stringFromNumber:number];
  if ([s isEqualToString:@"-0"]) return @"0";
  return s;
}
@end

Но если вы хотите что-то более сложное, это будет сложнее.

person abarnert    schedule 31.05.2012
comment
OK. Я пошел с перехватом значения в проблемном диапазоне и округлением его самостоятельно: float f = [number floatValue]; if (f < 0 && f > -0.5) number = [NSNumber numberWithLong:lround(f)]; - person Palimondo; 01.06.2012
comment
Обратите внимание, что манипуляции со строками, как показано здесь, не работают должным образом со всеми языковыми стандартами. Существуют другие символы, используемые для 0, а также потенциально другие символы для отрицательных значений. Вам лучше округлить число в числовой форме и позволить форматировщику чисел сделать свою работу. - person Palimondo; 18.07.2012
comment
@Palimondo: В ответе уже сказано, что предварительное округление… вероятно, ваш лучший вариант, и что даже если вы решите выполнить постобработку, то, что именно вы хотите сделать, вероятно, зависит от… того, что вы хотите сделать для локализаций, которые этого не делают. не используйте '-0', чтобы комментарий не добавлял никакой новой информации. - person abarnert; 18.07.2012
comment
Оно делает. Я хотел подчеркнуть потенциальную проблему для разработчиков с небольшим опытом интернационализации. - person Palimondo; 19.07.2012