Golang Float64bits

我正在尝试理解 Go Sqrt的实现,但不能完全理解该Float64bits函数发生了什么。我在下面有一些测试代码和输出。为什么 ix 的值会随着这个操作发生如此剧烈的变化?


package main


import ("math"

        "fmt")


func main()  {


    var x float64 = 4

    fmt.Printf("The value of x is: %v \n", x)


    ix := math.Float64bits(x)

    fmt.Printf("The value of ix is: %v \n", ix)

    fmt.Printf("The type of ix is: %T \n", ix)


}

The value of x is: 4 

The value of ix is: 4616189618054758400 

The type of ix is: uint64 


慕桂英4014372
浏览 265回答 3
3回答

哈士奇WWW

从文档中可以看出,它在不更改位的情况下将 转换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。

慕的地8271018

正如文档所说,该函数只是将构成浮点数的数据解释为 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. 因此,结果数字与浮点值完全不同。

慕尼黑的夜晚无繁华

 fmt.Printf 中使用 %#X 来格式化十六进制值。和 %[1] 来引用第一个参数,如下示例代码:package mainimport "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 = 4bits: 0X4010000000000000 = 4616189618054758400 uint64
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go