2016-06-10 33 views
0

我想了解Go Sqrt的實現,並不能完全理解Float64bits函數的功能。我有一些測試代碼和輸出如下。爲什麼ix的價值在這個操作中發生瞭如此劇烈的變化?Golang Float64bits

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 
+0

我相信你正在看的價值是十六進制。如果你知道浮點表示的公式(更多信息在這裏https://en.wikipedia.org/wiki/IEEE_floating_point),那麼你理論上可以將它應用到該值,它會給你4。 – evanmcdonnal

回答

2

從文檔中,它將float64轉換爲uint64而不更改位,這是位被解釋爲改變的方式。

這裏是Float64bits功能的完整源代碼:

func Float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) } 

不要使用不安全的指針的這種語法招害怕,這是相當常見的Go的源代碼(避免複製數據) 。所以,那真的很簡單:獲取給定float的二進制數據並將其解釋爲無符號整數。

它變化如此之大的原因是因爲浮點數的表示。根據規範,浮點數由符號,指數和尾數組成。

在一個64位浮點上,Sign有1位,指數有11位,尾數有52位。

作爲64個比特的浮點數的4表示爲:

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的。

1

正如documentation所說,函數只是將形成float的數據解釋爲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的比特。因此,結果數字與浮點值完全不同。

1

使用fmt.Printf中的%#X格式化十六進制值。和%[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 

和看到:

https://en.wikipedia.org/wiki/Double-precision_floating-point_formathttps://en.wikipedia.org/wiki/IEEE_floating_point

Why does adding 0.1 multiple times remain lossless?

golang: what does "%b" do in fmt.Printf for float64 and what is Min subnormal positive double in float64 in binary format?

我希望這有助於。