Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do these two float64s have different values?

Consider these two cases:

fmt.Println(912 * 0.01)
fmt.Println(float64(912) * 0.01)

(Go Playground link)

The second one prints 9.120000000000001, which is actually fine, I understand why that is happening.

However, why does the first line print 9.12, without the …01 at the end? Does Go multiply the two untyped constants and simply replace them with a 9.12 literal when compiling?

like image 760
Attila O. Avatar asked Jan 07 '15 12:01

Attila O.


1 Answers

As per spec:

Constant expressions are always evaluated exactly; intermediate values and the constants themselves may require precision significantly larger than supported by any predeclared type in the language.

Since

912 * 0.01

is a constant expression, it is evaluated exactly. Thus, writing fmt.Println(912 * 0.01) has the same effect as writing fmt.Println(9.12). When you pin 912 to float64, the other operand of the floating-point multiplication is implicitly pinned to float64, too. Thus, the expression float64(912) * 0.01 behaves like float64(912) * float64(0.01). 0.01 is not exactly representable in a float64, thus precision is lost in a different place than in the expression float64(912 * 0.01) which arises in the argument of fmt.Println() in your first example, explaining the different results.

like image 187
fuz Avatar answered Sep 29 '22 11:09

fuz