2012-06-10 39 views
4

如果我做的Objective-C如下:防止小负数印刷为“-0”

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

它会给结果@"-0.0"

有谁知道我怎么能强迫的结果@"0.0"(没有“ - ”)在这种情况下?

编辑: 我试过使用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.0fNSString *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"

最后请注意

对于它的价值,这里使用的方法/模式/算法将翻译成其他语言和不同的字符串格式化的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)]; 

编辑: 如果你只想0.0为正值:

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

感谢您的回答,但我只希望导致零打印而没有减号的值。例如,-0.1仍然应该导致@“ - 0.1”。 – fishinear

+0

感谢您的编辑。这种方法当然会起作用,但依赖于stringWithFormat:方法的内部结构的精确工作方式以及我正在使用的格式字符串。例如,您当前的方法对值-0.05产生不正确的“0.1”。我希望避免对内部进行那种微调。 – fishinear

+0

你是个好人。正如@sulthan所说,'NSNumberFormatter'是你的解决方案 – user1447414

1

使用NSNumberFormatter。通常,不应使用NSString格式将数据呈现给用户。

编辑: 正如问题所述,这不是正确的答案。有很多解决方案。检查负零点很容易,因为它定义为等于任何零(0.0f == -0.0f),但实际问题是其他许多值可以四舍五入至负零。我建议后处理 - 而不是捕捉这些值,它将检查结果是否只包含零数字(跳过其他字符)。如果是,请删除前导减号。

+0

呃,实际上这不是在这种情况下向用户展示。但除此之外,NSNumberFormatter似乎有相同的问题(请参阅编辑)。你知道在NSNumberFormatter上设置什么参数来防止这种情况吗? – fishinear

+0

糟糕。我希望格式化程序可以检查至少这(我已经使用我自己的格式化程序的NSDecimalNumbers)。看我的编辑。 – Sulthan

+0

所以我想没有简单的答案。我会接受你的回答,因为后处理至少避免了解操作的确切内部。 – fishinear

0

通过采用float或double值将数字转换为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