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
Libérer: 2024-12-09 17:01:10
original
917 Les gens l'ont consulté

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)
}
Copier après la connexion

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

After 54 iterations, a = 1.000000e+00
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal