0

NSDecimalNumber として格納されている値があり、それを double に変換すると精度が失われます。

現在デバッグしているデータの場合、値は 0.2676655 です。doubleValue メッセージを送信すると、0.267665 が返されます。丸めではなく切り捨てを行っており、ハッシュを使用して同期操作のデータ変更を検出する一部のコードに大混乱をもたらしています。

NSDecimalNumber インスタンスはサードパーティ フレームワークに由来するため、単純にプリミティブ double に置き換えることはできません。最終的には NSMutableString に挿入されるため、文字列表現を求めていますが、「%.6lf」のフォーマット指定子を介して渡す必要があります。基本的には、小数点以下 6 桁が必要なので、0.267666 のようになります。

精度を落とさずにこれを達成するにはどうすればよいですか? double に変換せずに NSDecimalNumber をフォーマットする良い方法があれば、それも機能します。

4

2 に答える 2

4

NSDecimalNumber インスタンスはサードパーティ フレームワークに由来するため、単純にプリミティブ double に置き換えることはできません。

はい、できます。NSDecimalNumber は NSNumber の不変のサブクラスであり、変換に関しては少し役に立ちます。

double myDub = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:((double)0.2676655)] doubleValue]];

最終的には NSMutableString に挿入されるため、文字列表現を求めていますが、「%.6lf」のフォーマット指定子を介して渡す必要があります。基本的には、小数点以下 6 桁が必要なので、0.267666 のようになります。

残念ながら、倍精度は丸められませんが、100 万分の 1 ずれている文字列値を取得することはそれほど大したことではありません (願っています)。

NSDecimalNumber *num = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:((double)0.2676655)] decimalValue]];
NSString *numString = [NSString stringWithFormat:@"%.6lf", [num doubleValue]];
NSLog(@"%@",numString);
于 2012-07-18T19:26:46.410 に答える
2

あなたは間違った道を進んでいて、どこかで何をすべきか迷っていると思います。

まず、objective-c では lond double はサポートされていないことに注意してください。そのため、%lf の代わりに %f などを使用することをお勧めします。[Objective C ランタイム プログラミング ガイドの「Type encodings」の下にあるドキュメント ライブラリにあります]

doubleValue は近似値を返しますが、使用している範囲はまだ正しい範囲内にあるため、値が切り捨てられて表示されることを期待します。

次のように、数値を移動する代わりに、単純なフォーマッタを使用する必要があります。

    // first line as an example for your real value
    NSDecimalNumber *value = [NSDecimalNumber decimalNumberWithString:@"0.2676655"];
    NSNumberFormatter *numFmt = [[NSNumberFormatter alloc] init];
    [numFmt setMaximumFractionDigits:6];
    [numFmt setMinimumFractionDigits:6];
    [numFmt setMinimumIntegerDigits:1];
    NSLog(@"Formatted number %@",[numFmt stringFromNumber:value]);

これには、必要に応じてロケール対応フォーマッターを使用するという別の利点があります。数値フォーマッタの結果は、目的の文字列です。

于 2012-07-18T20:52:22.183 に答える