The problem here is the representation of constants and floating point numbers.
Constants are represented by arbitrary precision. Floating-point numbers are represented using the IEEE 754 standard.
Spec: Constants:
Numeric constants represent arbitrary precision values ββand do not overflow.
Spec: Numeric Types:
float64 the set of all IEEE-754 64-bit floating-point numbers
The IEEE 754 uses double precision to store numbers, using 64 bits ( float64 in Go) 53 bits . This means that the maximum number (maximum number) that can be represented is the number of digits 2<<52 , which (1 bit for a character):
2<<52 : 9007199254740992 Your constant: 6161047830682206209
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 that you are trying to put into a variable of type float64 simply does not fit into 52 bits, so it must be rounded and the digits (or bits) will be truncated (lost).
You can verify this by typing the original n float64 number:
var n float64 = 6161047830682206209 fmt.Printf("%f\n", n) fmt.Printf("%d\n", uint64(n))
Output:
6161047830682206208.000000 6161047830682206208
The problem is not the conversion, the problem is that the float64 value you are trying to convert is no longer equal to the constant you tried to assign to it.
Just for curiosity:
Try the same with a much larger number: +500 compared to the first const:
n = 6161047830682206709 // +500 compared to first! fmt.Printf("%f\n", n2) fmt.Printf("%d\n", uint64(n2))
Print the same thing (last digits / bits are truncated, +500 are included!):
6161047830682206208.000000 6161047830682206208
Try a smaller number, the digits of which can be represented exactly using 52 bits (less than ~ 16 digits):
n = 7830682206209 fmt.Printf("%f\n", n) fmt.Printf("%d\n", uint64(n))
Output:
7830682206209.000000 7830682206209
Try it on the go playground .