package main
func main() {
var n float64 = 6161047830682206209
println(uint64(n))
}
The output will be:
6161047830682206208
It looks like that when float64
change to uint64
, the fraction is discarded.
package main
func main() {
var n float64 = 6161047830682206209
println(uint64(n))
}
The output will be:
6161047830682206208
It looks like that when float64
change to uint64
, the fraction is discarded.
The problem here is the representation of constants and floating point numbers.
Constants are represented in arbitrary precision. Floating point numbers are represented using the IEEE 754 standard.
Spec: Constants:
Spec: Numeric types:
In IEEE 754 the double precision which is using 64 bits (
float64
in Go) 53 bits are used to store the digits. This means the max digits (max number) that can be represented is the number of digits of2<<52
which is (1 bit is for sign):15.95 digits to be precise (16 digits, but not all values that you can describe with 16 digits, only up to
9007199254740992
).The integer constant you try to put into a variable of type
float64
simply does not fit into 52 bits so it has to be rounded and digits (or bits) will be cut off (lost).You can verify this by printing the original
n float64
number:Output:
The problem is not with conversion, the problem is that the
float64
value you try to convert is already not equal to the constant you tried to assign to it.Just for curiosity:
Try the same with a much bigger number: +500 compared to the first const:
Output still the same (the last digits / bits are cut off, +500 included!):
Try a smaller number whose digits can be represented precisely using 52 bits (less than ~16 digits):
Output:
Try it on the Go Playground.