我想要一个通用的解决方案,独立于数字格式化程序的配置。
我使用了一个类别将功能添加到 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"
您不想要的结果。
最后说明
对于它的价值,这里使用的方法/模式/算法将转换为其他语言和不同的字符串格式化 API。