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
Release: 2024-12-09 17:01:10
Original
928 people have browsed it

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)
}
Copy after login

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

After 54 iterations, a = 1.000000e+00
Copy after login

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
Copy after login

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
Copy after login

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
Copy after login

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
Copy after login

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!

source:php.cn
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template