数値フォーマッタの構成に関係なく、一般的な解決策が必要でした。
カテゴリを使用して機能を 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ます。
2 番目の重要な機能は、数値フォーマッタも、置換する正のゼロ文字列を提供するよう求められることです。これは、以前と同様に、そのフォーマットが尊重されるために必要です。これは、次の行で行われます。[self stringFromNumber: [NSNumber numberWithFloat: 0.0]]
うまくいかない最適化
入力数値が文字列としてフォーマットされるかどうかを自分で数値テストするのは魅力的です-0.0fが、これは非常に簡単ではありません (つまり、基本的に一般的には不可能です)。これは、-0.0f文字列にフォーマットされる数値のセットがフォーマッタの構成に依存するためです。if がたまたま最も近い百万に四捨五入されている場合-5,000f、入力は文字列としてフォーマットされ-0.0fます。
避けるべき実装エラー
文字列にフォーマットする入力-0.0fが検出されると、正のゼロに相当する出力文字列が を使用して生成され[self stringFromNumber: [NSNumber numberWithFloat: 0.0]]ます。具体的には、次の点に注意してください。
- このコードは float リテラル
0.0fをフォーマットして返します。
- コードは入力の否定を使用しません。
の入力を否定すると、-0.1fがフォーマットされ0.1fます。フォーマッタの動作によっては、これが切り上げられ、@"1,000"望ましくない結果になる可能性があります。
ファイナルノート
ここで使用されているアプローチ/パターン/アルゴリズムは、他の言語やさまざまな文字列フォーマット API に変換されます。