doubleタイプ演算精度喪失


この間pythonの入門を少し見て、いくつかの演算の例を書いたところ、浮動小数点数の演算の結果は期待ではなく、期待に近い数であることが分かった.例えば期待結果が2.4だったら、実際の結果は2.3333333339かもしれませんが、その時参考にした資料では気にしなくてもいいと言われていましたが、入門なのであまり気にしていませんでしたので、python自身の問題だと思っていました.昨日ネットをぶらぶらしていて、また間違いなくこの問題にぶつかったが、これはjavaの下で発生した.そこで例を書いてみると,この問題は特定の言語ではなく,コンピュータの下位実装に関係していることが分かったので,以下ではこの問題について述べる.
javaで浮動小数点数を使用する場合、デフォルトはdoubleです.floatを使用する必要がある場合は、浮動小数点数の後にfを加えます.
public class Test {

	public static void main(String[] args) {
		System.out.print("    2.4:");
		System.out.println(2.4);
		System.out.print("2.4/0.1:");
		System.out.println(2.4/0.1);
		System.out.print("(2.4-0.2)/0.1:");
		System.out.println((2.4-0.2)/0.1);
		System.out.print("    2.2:");
		System.out.println(2.2);
		System.out.print("2.2/0.1:");
		System.out.println(2.2/0.1);
		System.out.print("(2.2+0.2)/0.1:");
		System.out.println((2.2+0.2)/0.1);
        System.out.print("2.2+0.2:");
        System.out.println(2.2+0.2);
	}
}

出力結果:
    2.4:2.4
2.4/0.1:23.999999999999996
(2.4-0.2)/0.1:21.999999999999996
    2.2:2.2
2.2/0.1:22.0
(2.2+0.2)/0.1:24.000000000000004
2.2+0.2:2.4000000000000004

ソースコードと出力の結果から解析を行った.まず結果から,直接出力浮動小数点数2.2と2.4に問題はなく,すべて正常であることが分かった.しかし2.4/0.1出力24を期待していたが、23.9999999999999996を出力した.同様に、(2.4-0.2)/0.1期待出力は22、実出力は21.999999999999996、(2.2+0.2)/0.1も同様である.これらの現象は,計算中に精度損失が発生した「誤った結果」という非期待値を得たことを示している.
前述したように、pythonにもこのような問題があるので、この現象はある言語ではなく、コンピュータの実現によるものです.周知のように、コンピュータはバイナリしか認識できないので、私たちのすべてのデータは最後にバイナリに変換されて実現されます.直接出力2.4と2.2には問題はないが,演算に参加させるとエラーが発生するため,精度損失は「演算」の過程で発生することが分かった.
浮動小数点数は2つの部分からなり、指数と末尾数です.変換中に演算を行った場合,得られた結果は不明であり,バイナリが正確に10進数に変換できる保証はない.その原理は他の参考書を参照してください.
このような状況をどのように処理するかは、BigDecimalを使用して、JavaAPIを参照してください.