我试图理解Go 平方吨实现,但无法完全理解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 发布于 2016-06-10 23:31:10
从文档中,它在不改变位的情况下将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。您将在web上找到大量关于IEEE754的很好的教程,以充分了解上面的值是如何表示4的。
发布于 2016-06-10 23:09:21
正如文档所说,函数只是将形成浮点的数据解释为uint64。
IEEE 754双具有以下位布局:
SEEEEEEE EEEEMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM这些是64个双边投资条约,包括:
SEM值4.0等于此位表示:
01000000 00010000 00000000 00000000 00000000 00000000 00000000 00000000要详细解释为什么是这样看上去太长了。尾数有一些特殊的规则,在这里起着关键的作用。我们现在可以忽略这一点,如果您对IEEE浮动格式表示数字的所有肮脏细节感兴趣,请查看链接的文档。
上面的函数只会将这64位作为一个uint64来处理。最后,这只是抛出一堆恰好适合于uint64的比特。因此,结果数与浮点数完全不同。
发布于 2016-06-11 04:10:09
使用%#X在fmt.Printf中格式化十六进制值。和%1引用第一个arg,如下面的示例代码:
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并见:
金刚:在fmt.Printf中,float64的"%b“是做什么的?在二进制格式的float64中,”%b“是什么?
我希望这能帮到你。
https://stackoverflow.com/questions/37758267
复制相似问题