LoginSignup
2
0

More than 3 years have passed since last update.

Float計算回路の(ry-その1.1(float値の16進数表記)

Last updated at Posted at 2020-04-23

浮動小数点数の16進数表記を得る(SW)

前回
Float計算回路のVerilog-HDL実装について -その1

4/26 シミュレーション結果を追記
5/17 負の数のバグを修正

今回の内容

32bit float (single) が正しい値なのか
float値と16進表記値を相互変換するツールを作成する

cgo 使います

偉大な先駆者様(参考文献)

浮動小数点数の内部表現を取得してみよう

コード全体

今回作成したコード

check.go
package main

/*
union {float f; unsigned i;} uv;

int f2b(float inp) {
    uv.f = inp;
    return uv.i;
}

float b2f(unsigned inp) {
    uv.i = inp;
    return uv.f;
}
*/
import "C"
import (
    "fmt"
    "os"
    "strconv"
)

func main() {
    if os.Args[1] == "f" {
        fmt.Println("float -> hx")
        fv, _ := strconv.ParseFloat(os.Args[2], 32)
        f2h(float32(fv))
    } else if os.Args[1] == "h" {
        fmt.Println("hx -> float")
        hv, _ := strconv.ParseUint(os.Args[2], 16, 32)
        h2f(uint(hv))
    }
}

func h2f(inp uint) {
    float := float32(C.b2f(_Ctype_uint(inp)))
    fmt.Println(float)
}

func f2h(inp float32) {
    bits := int(C.f2b(_Ctype_float(inp)))

    fmt.Printf("Hex:%08X\n", bits)
    fmt.Printf("Exp:%02X\n", bits >> 23 & 0xFF)
    fmt.Printf("Fra:%X\n", bits & 0x7FFFFF)
}

共用体で値をコンバートしている

特殊なことはしていないのでCでも実装できると思う
(むしろGoだけで実装できるのか?)

テスト

$ go run check.go f 7.25
float -> hx
Hex:40E80000
Exp:81
Fra:680000

Exp のバイアス値 127 は 7F であるため
+2 された 81 が指数部の値となっている

また、680000 = 110 1000 0 0 0 0 なので
7.25 = 111.01 = 680000 x 2^2 となっていることがわかる

$ go run check.go h 40E80000
hx -> float
7.25

正しく戻せていることがわかる

シミュレーション結果の検証

7.25 + 11.625

7.25 + 11.625 = 18.875 \\
-> 40E8\_0000 + 413A\_0000 = 4197\_0000\\ 

Screenshot from 2020-04-26 20-05-25.png

あってるっぽい

12.345 + 3.1415926

12.345 + 3.1415926 = 15.4865926\\
-> 4145\_851F + 4049\_0FDA = 4177\_C915

Screenshot from 2020-04-26 20-09-04.png

あってるっぽい

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0