Go 如何将十六进制转换为浮点
我必须将Go 如何将十六进制转换为浮点,go,floating-point,hex,type-conversion,Go,Floating Point,Hex,Type Conversion,我必须将十六进制,重新表示为字符串s(例如“0xC40C5253”)转换为浮点值(IEEE-754转换)。我没有使用strconv.ParseFloat函数实现这一点。还有什么我必须用的吗? 到目前为止我还没找到。我还尝试先将其转换为整数,然后再转换为浮点,但结果是错误的 我最后一次尝试的代码: package main import ( "fmt" "strconv" ) func main () { x, err := strconv.ParseInt("C40C5253",
十六进制
,重新表示为字符串
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)
}
}
首先需要说明输入的位长度。由于十六进制表示法有4个字节(8个十六进制数字),它很可能是一个
float32
(需要询问者澄清)
您可以使用将十六进制表示形式中的字节解析为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浮点数的字节,可以使用该软件包:
f := *(*float32)(unsafe.Pointer(&n2))
fmt.Println(f)
输出(在上尝试):
注意:
正如JimB所指出的,对于第二部分(将uint32转换为浮动32),软件包有一个内置功能,它在引擎盖下完成以下功能:
f := math.Float32frombits(n2)
输入为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
这里有两种不同的方法可以产生-561.2863:
我从您的代码中获得
3.289141843e+09
。这是正确的吗?虽然它使用了相同的不安全方法,但是math
包中有这样的方法,但是结果必须是-561.2863,根据page@Jan区别在于数字是32位浮点,而不是您没有说明的64位浮点。这样做会得到预期的结果。@icza如果十六进制的大小表示128位的数字,那么此代码在ParseUint
@amitupadhayay时会失败,因为uint64
是64位的Go。如果你必须处理128位浮点数,那就开始吧。无需编辑其他答案。字节顺序也没有问题,因为数学包执行与*(*float32)(unsafe.Pointer(&b))
完全相同的不安全操作。在“上一个答案”上没有任何意义,答案会根据投票和读者选项重新排序。如果您需要参考其他答案,请使用“共享”链接获取链接。此外,仅链接的答案并不适合,因此,您应该将链接中的相关部分(在本例中为代码)包含在文章中。欢迎使用堆栈溢出!您还应该在答案中添加链接中的相关代码,而不是粘贴到解决方案的链接。这样,如果链接断开,答案仍然可用。
-561.2863
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
}