防止小负数打印为"-0"

fis*_*ear 4 objective-c zero nsnumber nsstring nsnumberformatter

如果我在Objective-C中执行以下操作:

NSString *result = [NSString stringWithFormat:@"%1.1f", -0.01];
Run Code Online (Sandbox Code Playgroud)

它会给出结果 @"-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]];
Run Code Online (Sandbox Code Playgroud)

Ben*_*ohn 5

我想要一个通用的解决方案,独立于数字格式化程序的配置.

我使用了一个类别来为NSNumberFormater添加功能;

@interface NSNumberFormatter (PreventNegativeZero)
- (NSString *)stringFromNumberWithoutNegativeZero:(NSNumber *)number;
@end
Run Code Online (Sandbox Code Playgroud)

随着实施:

@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
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

主要特点是要求数字格式将如何格式化-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]].请注意,具体来说:

  • 代码格式化float文字0.0f并返回它.
  • 代码使用输入的否定.

否定输入-0.1f会导致格式化0.1f.根据格式化程序的行为,这可能会被舍入并导致@"1,000",这是您不想要的.

最后的说明

对于它的价值,这里使用的方法/模式/算法将转换为其他语言和不同的字符串格式化API.