ホームページ >バックエンド開発 >Golang >`float32` を使用する Go プログラムが無限ループに入るのに対し、`float64` を使用する同様のプログラムは、1.0 を超えるまで 0.2 を加算したり 0.3 を減算したりすることを繰り返して終了するのはなぜですか?

`float32` を使用する Go プログラムが無限ループに入るのに対し、`float64` を使用する同様のプログラムは、1.0 を超えるまで 0.2 を加算したり 0.3 を減算したりすることを繰り返して終了するのはなぜですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-07 18:21:15286ブラウズ

Why does a Go program using `float32` enter an infinite loop while a similar program using `float64` terminates, when both accumulate 0.2 and subtract 0.3 iteratively until exceeding 1.0?

Go における浮動小数点精度の違い: float32 と float64

Go では、浮動小数点値は float32 または float64 として表現できます。 、さまざまなレベルの精度で。最近の実験では、プログラムで float32 型と float64 型の両方を使用したときに浮動小数点エラーが発生することが実証されました。

プログラムは、浮動小数点値 0.2 を複数回累積し、値が 1.0 を超えるまで反復ごとに 0.3 を減算します。 float64 を使用する場合、プログラムは 54 回の反復後に 1.000000e 00 を出力します。これは、C の同じプログラムの動作 (double を使用する場合) と同様です。

ただし、Go プログラムで float32 を使用すると、無限に入ります。ループ。この不一致は、Go と C が float32 表現を処理する方法が異なることから発生します。

浮動小数点表現の検証

math.Float32bits 関数と math.Float64bits 関数を使用して、 Go が 10 進数値を IEEE 754 バイナリとしてどのように表現するかを観察できます値:

float32(0.1): 00111101110011001100110011001101
float32(0.2): 00111110010011001100110011001101
float32(0.3): 00111110100110011001100110011010
float64(0.1): 0011111110111001100110011001100110011001100110011001100110011010
float64(0.2): 0011111111001001100110011001100110011001100110011001100110011010
float64(0.3): 0011111111010011001100110011001100110011001100110011001100110011

float32 精度の分析

これらのバイナリ値を 10 進数に変換すると、float32 を使用する Go プログラムの a の初期値が次のようになることがわかります。 >

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9
この負の値により、ループが到達することがなくなります。 1.0.

C 実装の違い

C では、float 定数の処理方法の違いにより動作が異なります。 Go は最も近いバイナリ表現で 0.1 を近似しますが、C は最後のビットを切り捨てる可能性があります。

Go:   00111101110011001100110011001101 => 0.10000000149011612
C(?): 00111101110011001100110011001100 => 0.09999999403953552
その結果、C では 0.1 をより正確に表現できるようになり、浮動小数点ループの結果が異なります。 float32 を使用する場合。

以上が`float32` を使用する Go プログラムが無限ループに入るのに対し、`float64` を使用する同様のプログラムは、1.0 を超えるまで 0.2 を加算したり 0.3 を減算したりすることを繰り返して終了するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。