Maison >développement back-end >Golang >Go vs C : Pourquoi la précision en virgule flottante provoque-t-elle une boucle infinie dans le Float32 de Go mais pas dans le Double de C ?

Go vs C : Pourquoi la précision en virgule flottante provoque-t-elle une boucle infinie dans le Float32 de Go mais pas dans le Double de C ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-09 17:01:10910parcourir

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

Précision à virgule flottante Go Lang : Float32 vs Float64

Pour illustrer les subtilités de l'arithmétique à virgule flottante dans Go, considérons le programme suivant démontrant la effet de précision :

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)
}

Ce programme présente le comportement attendu en C lors de l'utilisation du type double, impression :

After 54 iterations, a = 1.000000e+00

Cependant, lors de l'utilisation de float32 dans Go, le programme entre dans une boucle infinie. Modifier le programme C pour utiliser float au lieu de double donne un résultat différent :

After 27 iterations, a = 1.600000e+00

Pour comprendre cet écart, plongez dans les représentations binaires sous-jacentes à l'aide de math.Float32bits et 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

La conversion de ces valeurs binaires en décimales révèle que pour float32, la valeur initiale d'un devient :

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9

Cette valeur négative ne peut jamais totaliser 1, conduisant à la boucle infinie observée.

En revanche, le comportement de C découle des différences dans les stratégies d'arrondi. Faites le tour du dernier morceau, tandis que C le recadre probablement. Par conséquent, Go représente 0,1 comme la valeur la plus proche :

Go:   00111101110011001100110011001101 => 0.10000000149011612
C(?): 00111101110011001100110011001100 => 0.09999999403953552

En résumé, Go et C ne peuvent pas représenter avec précision 0,1 dans un flottant, mais Go utilise l'approximation la plus proche tandis que C peut le gérer différemment selon la mise en œuvre.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn