我必须将hex
转换为string
s(例如"0xC40C5253"
)以浮动值( IEEE-754 转换)。我没有设法使用strconv.ParseFloat函数。还有什么我必须使用的吗?
到目前为止我找不到它。我也尝试先将它转换为整数然后转换为浮点数,但结果是错误的。
我上次尝试的代码:
package main
import (
"fmt"
"strconv"
)
func main () {
x, err := strconv.ParseInt("C40C5253", 16, 64)
f, err := strconv.ParseFloat(fmt.Sprintf("%d", x), 64)
if err != nil {
fmt.Printf("Error in conversion: %s\n", err)
} else {
fmt.Println(f)
}
}
答案 0 :(得分:7)
首先需要说明输入的位长。由于十六进制表示有4个字节(8个十六进制数字),因此很可能是float32
(需要提问者澄清)。
您可以使用strconv.ParseUint()
将十六进制表示中的字节解析为uint32
。 ParseUint()
始终返回uint64
,它在内存中使用8个字节,因此您必须将其转换为uint32
,使用4个字节,就像float32
一样:
s := "C40C5253"
n, err := strconv.ParseUint(s, 16, 32)
if err != nil {
panic(err)
}
n2 = uint32(n)
现在你有了字节,但它们存储在uint32
类型的变量中,因此被解释为整数的字节。并且您希望将它们解释为IEEE-754浮点数的字节,您可以使用unsafe
包来执行此操作:
f := *(*float32)(unsafe.Pointer(&n2))
fmt.Println(f)
输出(在Go Playground上尝试):
-561.2863
注意:强>
正如JimB所指出的那样,对于第二部分(将uint32
翻译为float32
),math
包有一个内置函数math.Float32frombits()
,它正是在引擎盖下完成的:
f := math.Float32frombits(n2)
答案 1 :(得分:6)
以下两种不同的方法可以产生-561.2863:http://play.golang.org/p/Y60XB820Ib
import (
"bytes"
"encoding/binary"
"encoding/hex"
"math"
"strconv"
)
func parse_read(s string) (f float32, err error) {
b, err := hex.DecodeString(s)
if err != nil {
return
}
buf := bytes.NewReader(b)
err = binary.Read(buf, binary.BigEndian, &f)
return
}
func parse_math(s string) (f float32, err error) {
i, err := strconv.ParseUint(s, 16, 32)
if err != nil {
return
}
f = math.Float32frombits(uint32(i))
return
}
答案 2 :(得分:0)
输入为32位,因此必须视为32位数。它也是无符号的,因此应该解析为uint,而不是int。最后,不需要使用不安全的操作,事实上,这里使用它们将在具有不同字节顺序的机器上失败。
相反,请使用math.Float32frombits
,它完全符合您的要求:
package main
import (
"fmt"
"math"
"strconv"
)
func main() {
s := "C40C5253"
n, err := strconv.ParseUint(s, 16, 32)
if err != nil {
panic(err)
}
nn := uint32(n)
g := math.Float32frombits(nn)
fmt.Println(g)
}
输出:
-561.2863