golang十进制到十六进制转换错误

精度问题


设置是一个物理 i 按钮(1 线规范),带有制造商印刷的十六进制值(可信值)。物联网设备将二进制编码为十进制 - Golang 将接收到的值返回为十六进制。


接收到的十进制值为:


var V = 10736581604118680000

fmt.Sprintf("%016X", m.V)[2:14]) // adds uppercase and truncation of output

提供 000015877CD1


预期的可信输出是 000015877CD0


钥匙上刻有的十六进制是 95 000015877CD0 01


http://www.rapidtables.com/convert/number/decimal-to-hex.htm(可信?)表示使用的golang函数丢失了精度。编码为 19 位十进制数字的二进制值可以被 Golang 转换为十六进制而不会损失精度(使用上面的函数)


守着星空守着你
浏览 194回答 1
1回答

翻阅古今

例如,package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "math/big"&nbsp; &nbsp; "strconv")func hexdec(s string) uint64 {&nbsp; &nbsp; d := uint64(0)&nbsp; &nbsp; for i := 0; i < len(s); i++ {&nbsp; &nbsp; &nbsp; &nbsp; x := uint64(s[i])&nbsp; &nbsp; &nbsp; &nbsp; if x >= 'a' {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x -= 'a' - 'A'&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; d1 := x - '0'&nbsp; &nbsp; &nbsp; &nbsp; if d1 > 9 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d1 = 10 + d1 - ('A' - '0')&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if 0 > d1 || d1 > 15 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; panic("hexdec")&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; d = (16 * d) + d1&nbsp; &nbsp; }&nbsp; &nbsp; return d}func main() {&nbsp; &nbsp; x := "95000015877CD001"&nbsp; &nbsp; fmt.Println(x)&nbsp; &nbsp; n, err := strconv.ParseUint(x, 16, 64)&nbsp; &nbsp; fmt.Println(n, err)&nbsp; &nbsp; s := fmt.Sprintf("%016X", n)[2:14]&nbsp; &nbsp; fmt.Println(s)&nbsp; &nbsp; z, t := big.NewInt(0).SetString(x, 16)&nbsp; &nbsp; fmt.Println(z, t)&nbsp; &nbsp; s = fmt.Sprintf("%016X", z)[2:14]&nbsp; &nbsp; fmt.Println(s)&nbsp; &nbsp; fmt.Println(hexdec(x))}输出:95000015877CD00110736581604118679553 <nil>000015877CD010736581604118679553 true000015877CD010736581604118679553请注意,您已接近 64 位整数的限制:uint64&nbsp; the set of all unsigned 64-bit integers (0 to 18446744073709551615)在哪里Var V = 10736581604118680000来自?数字 10736581604118680000 是整数 10736581604118679553 的浮点近似值 (1.073658160411868e+19)。制造商可能不了解浮点:每个计算机科学家应该知道什么。给定整数 10736581604118680000,Go 计算出正确的结果。Go 在数学上是正确的。所以让我们试着告诉 Go 10736581604118680000 不是一个精确的整数,它是一个近似的浮点数。例如,package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "strconv")func main() {&nbsp; &nbsp; d := "10736581604118680000"&nbsp; &nbsp; f, err := strconv.ParseFloat(d, 64)&nbsp; &nbsp; fmt.Println(f, err)&nbsp; &nbsp; z := uint64(f)&nbsp; &nbsp; fmt.Println(z)&nbsp; &nbsp; s := fmt.Sprintf("%016X", z)[2:14]&nbsp; &nbsp; fmt.Println(s)}输出:1.073658160411868e+19 <nil>10736581604118679552000015877CD0虽然这个技巧在这种情况下有效,但不能保证在所有情况下都有效。真正的解决方案是制造商聘请一些有能力的数学家。我想知道他们的软件和硬件中还有哪些其他错误。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go