ホームページ > バックエンド開発 > Golang > Go vs. C: 浮動小数点精度によって Go の Float32 では無限ループが発生するのに、C の Double では発生しないのはなぜですか?

Go vs. C: 浮動小数点精度によって Go の Float32 では無限ループが発生するのに、C の Double では発生しないのはなぜですか?

Barbara Streisand
リリース: 2024-12-09 17:01:10
オリジナル
918 人が閲覧しました

Go vs. C: Why Does Floating-Point Precision Cause an Infinite Loop in Go's Float32 but Not in C's Double?

Go Lang 浮動小数点精度: Float32 と Float64

Go の浮動小数点演算の複雑さを説明するために、次のプログラムを考えてみましょう。精度の効果:

func main() {
    a := float64(0.2)
    a += 0.1
    a -= 0.3
    var i int
    for i = 0; a < 1.0; i++ {
        a += a
    }
    fmt.Printf("After %d iterations, a = %e\n", i, a)
}
ログイン後にコピー

これdouble 型を使用すると、プログラムは C で予期される動作を示し、

After 54 iterations, a = 1.000000e+00
ログイン後にコピー

を表示します。ただし、Go で float32 を使用すると、プログラムは無限ループに入ります。 C プログラムを変更して double の代わりに float を使用すると、異なる結果が得られます:

After 27 iterations, a = 1.600000e+00
ログイン後にコピー

この矛盾を理解するには、math.Float32bits と math.Float64bits を使用して基礎となるバイナリ表現を詳しく調べてください:

float32(0.1): 00111101110011001100110011001101
float32(0.2): 00111110010011001100110011001101
float32(0.3): 00111110100110011001100110011010
float64(0.1): 0011111110111001100110011001100110011001100110011001100110011010
float64(0.2): 0011111111001001100110011001100110011001100110011001100110011010
float64(0.3): 0011111111010011001100110011001100110011001100110011001100110011
ログイン後にコピー

これらのバイナリ値を 10 進数に変換すると、float32 の場合、

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9
ログイン後にコピー

この負の値は合計が 1 になることはなく、観察された無限ループにつながります。

対照的に、C の動作は丸め戦略の違いに起因します。 Go は最後のビットを丸めますが、C はおそらくそれをトリミングします。その結果、Go は 0.1 に最も近い値として 0.1 を表します。

Go:   00111101110011001100110011001101 => 0.10000000149011612
C(?): 00111101110011001100110011001100 => 0.09999999403953552
ログイン後にコピー

要約すると、Go と C はどちらも float で 0.1 を正確に表すことはできませんが、Go は最も近い近似を使用するのに対し、C は状況に応じて異なる方法で処理する可能性があります。実装。

以上がGo vs. C: 浮動小数点精度によって Go の Float32 では無限ループが発生するのに、C の Double では発生しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート