Floating-Point Precision Differences in Go: Literals vs Variables
In Go, the behavior of floating-point arithmetic can seem contradictory when comparing operations involving literals and variables. Let's examine the following code:
package main import ( "fmt" ) func main() { x := 10.1 fmt.Println("x == 10.1: ", x == 10.1) fmt.Println("x*3.0 == 10.1*3.0:", x*3.0 == 10.1*3.0) fmt.Println("x*3.0: ", x*3.0) fmt.Println("10.1*3.0: ", 10.1*3.0) }
When executed, this code displays the following output:
x == 10.1: true x*3.0 == 10.1*3.0: false x*3.0: 30.299999999999997 10.1*3.0: 30.3
As seen in the output, the comparison of x*3.0 and 10.1*3.0 unexpectedly evaluates to false. This raises the question of why this discrepancy occurs and whether it's intentional or a bug.
Understanding the Design
In Go, floating-point literals and constants have unlimited precision. However, when they're assigned to typed variables, their precision is constrained by the bounds of the target type. In the example above, x := 10.1 stores the literal 10.1 in a float64 variable. This conversion introduces some loss of precision due to the limitations of the float64 type.
In contrast, the expression 10.1*3.0 performs floating-point multiplication directly on the literals, preserving their full precision. This results in a slightly different value compared to x*3.0, where the reduced precision of x affects the calculation.
Documentation and Resources
The official Go documentation acknowledges this behavior under the "Floats" section of the Constants article. It explains that while numeric constants have arbitrary precision, they must fit into the destination type when assigned. Large values like 1e1000 can be used in expressions with other constants, but their precision may be affected when the result is stored in a narrower type.
Although the article doesn't explicitly mention the specific behavior observed in our example (x*3.0 vs. 10.1*3.0), it provides a general understanding of how precision limitations apply to constants and typed variables.
The above is the detailed content of Why do floating-point comparisons in Go yield different results for literals and variables?. For more information, please follow other related articles on the PHP Chinese website!