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

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

Barbara Streisand
Barbara StreisandOriginal
2024-12-09 17:01:10910browse

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

Go Lang Floating Point Precision: Float32 vs Float64

To illustrate the intricacies of floating point arithmetic in Go, consider the following program demonstrating the effect of precision:

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

This program exhibits the expected behavior in C when using the double type, printing:

After 54 iterations, a = 1.000000e+00

However, when using float32 in Go, the program enters an infinite loop. Modifying the C program to use float instead of double yields a different result:

After 27 iterations, a = 1.600000e+00

To understand this discrepancy, delve into the underlying binary representations using math.Float32bits and 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

Converting these binary values to decimal reveals that for float32, the initial value of a becomes:

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9

This negative value can never sum up to 1, leading to the observed infinite loop.

In contrast, C's behavior stems from the differences in rounding strategies. Go rounds the last bit, while C likely crops it. Consequently, Go represents 0.1 as the value closest to it:

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

In summary, both Go and C cannot precisely represent 0.1 in a float, but Go uses the closest approximation while C may handle it differently depending on the implementation.

The above is the detailed content of Go vs. C: Why Does Floating-Point Precision Cause an Infinite Loop in Go's Float32 but Not in C's Double?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn