数値フォーマッタの構成に関係なく、一般的な解決策が必要でした。
カテゴリを使用して機能を 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
ます。
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 に変換されます。