3 回答
TA贡献1799条经验 获得超6个赞
从文档中可以看出,它在不更改位的情况下将 转换float64为uint64,这是位被解释的方式发生了变化。
以下是该Float64bits函数的完整源代码:
func Float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) }
不要被使用不安全指针的语法技巧吓到,它在 Go 的源代码中很常见(避免复制数据)。所以,这真的很简单:获取给定浮点数的二进制数据并将其解释为无符号整数。
它变化如此之大的原因是浮点数的表示。根据规范,浮点数由符号、指数和尾数组成。
在 64 位浮点数上,符号位为 1 位,指数为 11 位,尾数为 52 位。
4 作为 64 位浮点数的表示形式是:
0b0100 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
SEEE EEEE EEEE MMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM MMMM
事实证明,如果将其解释为无符号整数,则该值为 4616189618054758400。您会在网上找到很多关于 IEEE754 的精彩教程,以充分了解上述值如何表示 4。
TA贡献1796条经验 获得超4个赞
正如文档所说,该函数只是将构成浮点数的数据解释为 uint64。
IEEE 754 double具有以下位布局:
SEEEEEEE EEEEMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM
这些是 64 位,包括:
一个符号位
S
指数位
E
尾数位
M
该值4.0
等于此位表示:
01000000 00010000 00000000 00000000 00000000 00000000 00000000 00000000
一个详细的解释为什么是这样看起来太冗长了。有一些关于尾数的特殊规则在这里起着关键作用。我们现在可以忽略这一点,如果您对 IEEE 浮点格式中数字表示的所有脏细节感兴趣,请查看链接文档。
上面的函数没有做任何其他事情,因为将这 64 位视为uint64
. 最后,这只是将一堆恰好适合uint64
. 因此,结果数字与浮点值完全不同。
TA贡献1864条经验 获得超6个赞
fmt.Printf 中使用 %#X 来格式化十六进制值。和 %[1] 来引用第一个参数,如下示例代码:
package main
import "fmt"
import "math"
func main() {
var x float64 = 4
fmt.Println("x =", x)
ix := math.Float64bits(x)
fmt.Printf("bits: %#X = %[1]v %[1]T\n", ix)
}
输出:
x = 4
bits: 0X4010000000000000 = 4616189618054758400 uint64
- 3 回答
- 0 关注
- 249 浏览
添加回答
举报