5

Objective-Cで次のことを行うと:

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]];
4

4 に答える 4

6

数値フォーマッタの構成に関係なく、一般的な解決策が必要でした。

カテゴリを使用して機能を 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 に変換されます。

于 2013-11-18T13:26:24.720 に答える
1

を使用しNSNumberFormatterます。一般に、NSStringフォーマットはユーザーにデータを提示するために使用されるべきではありません。

編集:質問で述べたように、これは正しい答えではありません。いくつかの解決策があります。負のゼロは任意のゼロ()と等しくなるように定義されているため、簡単に確認できます0.0f == -0.0fが、実際の問題は、他の多くの値を負のゼロに丸めることができることです。そのような値をキャッチする代わりに、後処理をお勧めします。これは、結果に0桁しか含まれていないかどうかをチェックする関数です(他の文字をスキップします)。はいの場合、先頭のマイナス記号を削除します。

于 2012-06-10T16:52:55.223 に答える
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];
于 2012-06-10T14:27:29.870 に答える