如何以正确的方式将float64数字更改为uint64? [英] How to change a float64 number to uint64 in a right way?
问题描述
package main
func main(){
var n float64 = 6161047830682206209
println(uint64(n))
}
输出将会是:
6161047830682206208
看起来像 float64
更改为 uint64
,分数被丢弃。 / div>
这里的问题是表示常量和浮点数。
常量以任意精度表示。浮点数使用 IEEE 754 标准来表示。
数字常量表示任意精度的值,不会溢出。
float64所有IEEE-754 64位浮点数的集合
在IEEE 754中,使用64位(在Go中 float64
)的双精度 53位用于存储数字。这意味着可以表示的最大数字(最大数字)是 2 <52
的位数(1位是符号):
2 <<< 528 $ 900 pre>
15.95数字是准确的(16位数字,但不是所有可用16位数字描述的值,只能达到 9007199254740992 $ c
您试图放入 float64
变量的整数常量只是不适合到52位,所以它必须被舍入,并且数字(或位)将被切断(丢失)。
打印原始 n float64
数字:
var n float64 = 6161047830682206209
fmt.Printf(%f \ n,n)
fmt.Printf(%d\\\
,uint64(n))
输出:
6161047830682206208.000000
6161047830682206208
问题不在于转换,问题在于 float64
尝试转换已经不等于你试图分配给它的常量。
只是为了好奇:
尝试与更大的数字相同:+500与第一个const相比:
n = 6161047830682206709 // +500相比第一!
fmt.Printf(%f \ n,n2)
fmt.Printf(%d\\\
,uint64(n2))
输出仍然相同(最后的数字/位被截断,+500包括在内):
6161047830682206208.000000
6161047830682206208
尝试使用52位(小于〜16位)精确表示一个小数字:
n = 7830682206209
fmt.Printf(%f \ n,n)
fmt.Printf(%d\\\
,uint64(n))
$ c $输出:
7830682206209.000000 $ b $ $ b>
b 7830682206209
试试 Go Playground 。
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.
Numeric constants represent values of arbitrary precision and do not overflow.
float64 the set of all IEEE-754 64-bit floating-point numbers
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 of 2<<52
which is (1 bit is for sign):
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 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:
var n float64 = 6161047830682206209
fmt.Printf("%f\n", n)
fmt.Printf("%d\n", uint64(n))
Output:
6161047830682206208.000000
6161047830682206208
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:
n = 6161047830682206709 // +500 compared to first!
fmt.Printf("%f\n", n2)
fmt.Printf("%d\n", uint64(n2))
Output still the same (the last digits / bits are cut off, +500 included!):
6161047830682206208.000000
6161047830682206208
Try a smaller number whose digits can be represented precisely 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.
这篇关于如何以正确的方式将float64数字更改为uint64?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!