2009-07-07 10 views
1

私は、initWithContentsOfFileで再構成したときにNSValuesにアンパックする "Numbers"(0.01、1、2、6)の配列を持つplist(XCodeで作成)を取得しました。これらのNSValuesをNSDecimalNumbersに変換するにはどうしたらいいですか?これらは通貨価値として扱われるので、小数点以下2桁(おそらく4桁)の精度が必要です。NSValueをNSDecimalNumberに変換する

plist値を "Number"ではなく "String"として保存し、NSDecimalNumberのinitWithStringを使用して値を設定しようとしましたが、NSValueはstringValueに応答しません。

数字を扱うように見えますが、特にココアでは混乱します。 :

答えて

0

覚えておくべき最初の教訓は、精度を求めたい場合は、浮動小数点(10進数)ではなく整数を使用することです。あなたがセントを表示する必要があるときはいつでも100.0)。コンピュータはバイナリ(ベース2)で完璧ですが、1/(2^n)のファクタに分解できないバイナリを表現しようとすると、精密エラーに陥ります。 (0.1 + 0.1で試してみてください)

つまり、数値を指定するXMLタグは、-[NSArray initWithContentsOfFile:]のようなものを使用すると、値がココアのクラスでどのように解釈されるかに違いがありますそれを「再構成する」。に相談する詳細および例については、3210およびthis Apple articleを参照してください。

あなたが求めていることを達成するには、あなたのplistの値の周りに<real>または<integer>(と一致する終了タグ)を使用していることを確認してください。 (プロパティリストエディタとXcodeは、数値に小数点があるかどうかに基づいて自動的に正しいものを使用する必要があります。)私のテストでは、実数と整数の両方がNSNumberオブジェクトとして読み込まれました。 NSDecimalNumberはNSNumberのサブクラスですが、CFNumberとのフリーダイヤルによるブリッジングがすべての場合にどのように機能するかについては完全にはわかりません。おそらくこれを理解するには実験が最適な方法でしょう。

+0

100倍乗算のアプローチはMOST通貨にとっては優れていますが、普遍的ではありません。現在のロケールのNSNumberFormatterからmaximumFractionDigitsを取得してから、10^maxDigitsで整数を掛けることができると思います。それでも、この現代のコンピューティングでは、通貨と同じように何かを操作するのは難しい/混乱するべきではないようです。 – Meltemi

+0

これは混乱しないといいでしょう。しかし、バイナリ/小数点の問題として、私たちがお金をバイナリに変えない限り、その周りに簡単な方法はありません。 :-) –

1

数字を文字列として直接プロパティリストに保存することができます。 plistにNSStringを格納するときに、NSStringのNSValueラッピングを行う必要はありません。 NSDecimalsやNSDecimalNumbersのように、アプリケーション内の数値を浮動小数点エラーを避け、plistからinitWithString:localeを使って読み込み、descriptionWithLocale:を使用してplistに書き込むことをお勧めします。小数点を文字列として格納および取得することで、浮動小数点変換エラーの発生を回避します。

関連する問題