2012-06-10 1 views
4

Если я сделать следующее в Objective-C:Предотвратить небольшой отрицательные числа печати, как «-0»

NSString *result = [NSString stringWithFormat:@"%1.1f", -0.01]; 

Это даст результата @"-0.0"

Кто-нибудь знает, как я могу заставить результат @"0.0" (без «-») в этом случае?

EDIT: Я пробовал использовать NSNumberFormatter, но у него такая же проблема. Ниже также производит @"-0.0":

double value = -0.01; 
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; 
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; 
[numberFormatter setMaximumFractionDigits:1]; 
[numberFormatter setMinimumFractionDigits:1]; 
NSString *result = [numberFormatter stringFromNumber:[NSNumber numberWithDouble:value]]; 

ответ

5

Я хотел получить общее решение, независимо от конфигурации форматирования чисел.

Я использовал категорию, чтобы добавить функциональность в NSNumberFormater;

@interface NSNumberFormatter (PreventNegativeZero) 
- (NSString *)stringFromNumberWithoutNegativeZero:(NSNumber *)number; 
@end 

С внедрением:

@implementation NSNumberFormatter (PreventNegativeZero) 

- (NSString *)stringFromNumberWithoutNegativeZero:(NSNumber *)number 
{ 
    NSString *const string = [self stringFromNumber: number]; 
    NSString *const negZeroString = [self stringFromNumber: [NSNumber numberWithFloat: -0.0f]]; 

    if([string isEqualToString: negZeroString]) 
    { 
     NSString *const posZeroString = [self stringFromNumber: [NSNumber numberWithFloat: 0.0]]; 
     return posZeroString; 
    } 

    return string; 
} 

@end 

Как это работает

Ключевой особенностью это спросить номер форматировщик, как он будет отформатирован -0.0f (т.е. с плавающей точкой минус ноль) NSString, чтобы мы могли обнаружить это и принять меры по исправлению положения.

Зачем это делать? В зависимости от конфигурации форматировочной, -0.0f может быть отформатирован как: @"-0", @"-0.0", @"-000", @"-0ºC", @"£-0.00", @"----0.0", @"(0.0)", @".⓪零" действительно, довольно много ничего. Итак, мы спросить форматере, как это будет формат -0.0f с помощью строки: NSString *const negZeroString = [self stringFromNumber: [NSNumber numberWithFloat: -0.0f]];

вооружившись нежелательному -0.0f строки, когда произвольное число входных отформатирован, он может быть проверен, чтобы увидеть, если она соответствует нежелательным -0.0f строка.

Вторая важная особенность заключается в том, что число форматера также запрашивается для замены положительной нулевой строки. Это необходимо для того, чтобы по-прежнему соблюдалось его форматирование. Это делается с помощью строки: [self stringFromNumber: [NSNumber numberWithFloat: 0.0]]

Оптимизация, которая не работает

Заманчиво выполнить численный тест самостоятельно для будет ли введенный номер будет отформатирован как -0.0f строки, но это крайне нетривиальным (т. е. вообще невозможно вообще). Это связано с тем, что набор чисел, который будет отформатирован до строки -0.0f, зависит от конфигурации форматирования. Если округление округляется до ближайшего миллиона, то -5,000f в качестве ввода будет отформатирован как строка -0.0f.

ошибка реализации, чтобы избежать

Когда вход, который форматирует к -0.0f строке обнаруживаются, положительная нулевая эквивалентная выходная строка генерируется с использованием [self stringFromNumber: [NSNumber numberWithFloat: 0.0]]. Обратите внимание, что, в частности:

  • Код форматирует поплавок буквального 0.0f и возвращает его.
  • Код не использовать отрицание ввода.

Отрицание ввода -0.1f приведет к форматированию 0.1f. В зависимости от поведения форматирования это можно округлить и привести к @"1,000", который вам не нужен.

Final Примечание

Для чего это стоит, подход/шаблон/алгоритм, используемый здесь будет переводить на другие языки и разные строки форматирования API.

+0

Отличный ответ – fishinear

+0

Спасибо @fishinear, лучше поздно, чем никогда, надеюсь :-) – Benjohn

0
NSString *result = [NSString stringWithFormat:@"%1.1f", -0.01*-1]; 

Если вместо значения вы передаете экземпляр вы можете проверить:

float myFloat = -0.01; 
NSString *result = [NSString stringWithFormat:@"%1.1f", (myFloat<0? myFloat*-1:myFloat)]; 

Edit: Если вы просто хотите, 0.0, как положительное значение:

NSString *result = [NSString stringWithFormat:@"%1.1f",(int)(myFloat*10)<0?myFloat:myFloat*-1]; 
+0

Спасибо за ваш ответ, но мне нужны только значения, которые приводят к нулю для печати без знака минус. Например, -0.1 должно по-прежнему приводить к @ "- 0,1". – fishinear

+0

Спасибо за редактирование. Разумеется, такой подход будет работать, но зависит от точной работы внутренних элементов метода stringWithFormat: и от используемой строки форматирования. Например, ваш текущий подход создает неверный «0,1» для значения -0,05. Я надеялся избежать такой тонкой настройки на внутренности. – fishinear

+0

Вы на высоте. Как сказал @sulthan, «NSNumberFormatter» - это ваше решение. – user1447414

1

Использовать NSNumberFormatter. В общем случае форматирование NSString не должно использоваться для представления данных пользователю.

EDIT: Как указано в вопросе, это неправильный ответ. Существует ряд решений. Легко проверить отрицательный ноль, потому что он определен как равный любому нулю (0.0f == -0.0f), но актуальной проблемой является то, что ряд других значений можно округлить до отрицательного нуля. Вместо того, чтобы ловить такие значения, я предлагаю постобработку - функцию, которая проверяет, содержит ли результат только нулевые цифры (пропускание других символов). Если да, удалите знак «минус».

+0

Ну, на самом деле это не для представления пользователю в этом случае. Но кроме того, NSNumberFormatter, похоже, имеет такую ​​же проблему (см. Править). Знаете ли вы, какой параметр установить для NSNumberFormatter, чтобы предотвратить это? – fishinear

+0

Упс. Я надеялся, что форматер может проверить хотя бы это (я уже использую собственный форматтер для NSDecimalNumbers). См. Мое редактирование. – Sulthan

+0

Так что, я думаю, нет простого ответа. Я отвечу на ваш ответ, потому что пост-обработка, по крайней мере, позволяет избежать необходимости знать точные внутренние операции. – fishinear

0

Преобразуйте число в NSString, взяв поплавок или двойное значение. Преобразуйте строку обратно в NSNumber.

NSDecimalNumber *num = [NSDecimalNumber decimalNumberWithString:@"-0.00000000008"]; 
    NSString *st2 = [NSString stringWithFormat:@"%0.2f", [num floatValue]]; 
    NSDecimalNumber *result = [NSDecimalNumber decimalNumberWithString:st2]; //returns 0 
+0

floatValue также округляет десятичное число. – ArunGJ