これは非常に基本的な質問かもしれませんが、実際に何が起こっているのか知りたいです。
たとえば、c# で次のようにするとします。
object obj = "330.1500249000119";
var val = Convert.ToDouble(obj);
値は次のようになります: 330.15002490001189
問題は、なぜ最後の 9 が 89 に置き換えられるのかということです。このようになるのを止めることはできますか?そして、この精度は現在の文化に依存していますか?
これは非常に基本的な質問かもしれませんが、実際に何が起こっているのか知りたいです。
たとえば、c# で次のようにするとします。
object obj = "330.1500249000119";
var val = Convert.ToDouble(obj);
値は次のようになります: 330.15002490001189
問題は、なぜ最後の 9 が 89 に置き換えられるのかということです。このようになるのを止めることはできますか?そして、この精度は現在の文化に依存していますか?
これは文化とは何の関係もありません。基数 10 の 1/3 を .3333333 で正確に表すことができないのと同様に、基数 2 の数で正確に表すことができない数もあります。
特定のケースでは、データ型で許可されているよりも多くの桁を入力していることに注意してください。Double で使用できる有効桁数は 15 ~ 16 (範囲によって異なります) であり、これを超えています。
この場合、 a の代わりに aDoubleを使用できます。Decimal
object obj = "330.1500249000119";
var val = Convert.ToDecimal(obj);
Adecimalは精度を保持します。
object obj = "330.1500249000119";
var val = Convert.ToDecimal(obj);
あなたが抱えている「問題」は浮動小数点表現です。
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
いいえ、それを止めることはできません。データ型が表現できる桁数が多い値を解析しています。
精度は文化に依存しません。Adoubleは常に同じ精度です。
したがって、それが発生したくない場合は、単純に実行しないでください。浮動小数点数の制限された精度の影響が望ましくない場合は、浮動小数点数を使用しないでください。代わりに固定小数点数 (Decimal) を使用すると、値を正確に表すことができます。
CPU は double を 8 バイトで表します。これは、1 符号ビット、指数 (「範囲」) 用の 11 ビット、および仮数 (「精度」) 用の 52 ビットに分割されます。範囲と精度が限られています。
の C 定数DBL_DIGは、そのような double が正確に15 桁<float.h>しか表現できないことを示しています。ただし、この数は、c ライブラリと CPU に完全に依存します。
330.1500249000119 は 18 桁なので、330.150024900012 に丸められます。330.15002490001189 は 1 回限りで、これで問題ありません。通常、1.189 対 1.2 を期待する必要があります。
背後にある正確な数学については、David Goldberg の「What Every Computer Scientist Should Know About Floating-point Arithmetic」、ACM Computing Surveys 23、1 (1991-03)、5-48 を読んでみてください。詳細に興味がある場合は読む価値がありますが、コンピューター サイエンスのバックグラウンドが必要です。 http://www.validlab.com/goldberg/paper.pdf
long double や __float128 などのより優れた浮動小数点型を使用するか、HW でネイティブに long double として 41 桁 (__float128) を使用する Sparc64 や s390 などのより優れた CPU を使用することで、これを防ぐことができます。
はい、UltraSparc/Niagara または IBM S390 を使用することは文化です。
通常の答えは次のとおりです: long doubleを使用してください。これにより、Intel ではさらに 2 バイト (18 桁)、powerpc ではさらに数バイト (31 桁)、sparc64/s390 では 41 バイトが得られます。