Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何将十六进制转换为浮点_Go_Floating Point_Hex_Type Conversion - Fatal编程技术网

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
}