2016-08-24 8 views
8

私のSwiftアプリケーションでは、何らかの理由でNSNumberに変換するときに問題が発生することがあります。私のアプリは2桁の小数点以下の桁数(価格)をNSNumbersに変換してコアデータを使用して格納および検索できるようにする必要があります。たとえば、NSNumberのdoubleValueメソッドを使用して特別にフォーマットされていない限り、79.99などの特定の価格は99.98999999999999と評価されます。ここでSwiftでNSNumberに変換する精度が

selectedWarranty.price = 79.99、私は理由がある場合、誰かが説明することができ、変換が

Original double: 79.99 
Converted to NSNumber: 79.98999999999999 
.doubleValue Representation: 79.99 

をどのように動作するかを示すために、いくつかのprint文をプログラムデバッガ

// item.price: NSNumber?  
// selectedWarranty.price: Double? 

item.price = NSNumber(double: selectedWarranty.price!) 

に示すように、イニシャライザは確実にすべての数値に対して小数点以下2桁を保持できませんか?コアデータに価格を保管するのが本当に好きです。それが表示されるたびにフォーマットするのはとても便利ではありません。

UPDATE:データモデルを通じてNSDecimalNumberを入力する 変換されたコアデータオブジェクト、79.99と99.99もはや問題ではなく、異なる数と今より管理の問題...まず

Original double: 39.99 
Converted to NSDecimalNumber: 39.99000000000001024 
+1

[最小限の、完全で検証可能な例を作成してください](http://stackoverflow.com/help/mcve) – Alexander

+1

通貨に「NSNumber」の代わりに「NSDecimalNumber」を使用します。 – rmaddy

+0

この問題は再現できません。 http://swiftlang.ng.bluemix.net/#/repl/57bdc2590dcf4abf47da28c2 – Alexander

答えて

9

、あなた」いくつかの用語を混乱させる。 79.98999999999999は、精度が79.99(小数点の拡張が長くなります)よりも精度は高くなりますが、精度は低くなります(真の値から逸脱します)。

第2に、NSNumberには79.9979.98999999999999も格納されません。 IEEE 754標準に従って値の大きさを格納します。あなたが目にしているのは、その大きさを人間が読める数に変換するために適用されている印刷ロジックの結果でしょう。いずれにせよ、一定の精度で値を格納するには、FloatまたはDoubleに頼るべきではありません。非常に本質的に、表現可能な値のより長い範囲を得るために精度を犠牲にします。

IntのセントまたはNSDecimalNumberとして価格を表す方がはるかに良いでしょう。

はどこでもどのように二重の作品だWhy not use Double or Float to represent currency?

+0

ありがとうございます。 NSDecimalNumberルートが最適です。私の唯一の質問は、コアデータモデルをNSNumberの代わりに使用できるようにする方法です。私はこの分野ではあまり経験がありません – joelrorseth

+0

私はそれについて新しい質問を開こうとするとわかりません。この回答があなたの直ぐ質問を満足していると感じたら、それを受け入れたものとしてマークしてください:) – Alexander

1

を参照してください。小数点以下2桁しか必要ない場合は、2桁目の後にポイントを追加する代わりに整数/ロングを使用することを検討してください。

関連する問題