将大整数 (uint64+) 转换为十六进制

Converting large integer (uint64+) into hex

提问人:yingw 提问时间:11/8/2023 最后编辑:yingw 更新时间:11/9/2023 访问量:48

问:

在将内容导入 bigquery 时,我的十六进制字符串被转换为浮点数。我知道我需要修复导入,但我想尽最大努力恢复一些数据。

我正在尽最大努力将它们转换回十六进制,但是,尝试玩具示例会产生意想不到的行为。

前任。给定以下十六进制值:

hh = 0x6de517a18f003625e7fba9b9dc29b310f2e3026bbeb1997b3ada9de1e3cec8d6
# int: 49706871569187420659586066466638340615522392400360198520171375183123350210774
# float: 4.9706871569187424e+76

我不确定为什么最后几位数字在浮点数中从 420 到 424

尝试将此值转换为浮点数,然后再将其变回十六进制会严重截断该值

ff = 4.9706871569187424e+76 # same as calling float.fromhex('0x6de517a18f003625e7fba9b9dc29b310f2e3026bbeb1997b3ada9de1e3cec8d6')
int(ff) # 49706871569187423635521182730432496296162592228596139982404260202468916330496
# not sure why getting so many significant figures
hex(int(ff))
# '0x6de517a18f003800000000000000000000000000000000000000000000000000'

对我来说,这是出乎意料的,因为十六进制中的最后一个非零值发生了变化。(0036->0038) 我假设这与尾数的表示方式有关,但希望这里有人能快速回答,而不是深入研究 python 中的浮点实现。

Python 浮点整 十六进制 int128

评论

3赞 user2357112 11/8/2023
您需要修复导入数据的方式。您无法在后处理中解决这个问题 - 您丢弃了部分数据。
3赞 John Kugelman 11/8/2023
hh包含 64 个十六进制数字,即 256 位。浮点数只有 64 位。
0赞 Mark Tolonen 11/8/2023
float.fromhex(hh)返回,所以声明是假的。 给出了这个数字,但正如其他人所说,浮点数是 64 位,并且该数字被截断了。TypeError: bad argument type for built-in operationff = 4.9706871569187424e+76 # same as calling float.fromhex(hh)float(hh)
1赞 Mark Tolonen 11/8/2023
事实上,float64 的尾数是 53 位(其他位是符号和指数),而 ur 中的最后一个非零位是第 52 位,这就是为什么它从 36(0110110 二进制)四舍五入到 0038(0111000 二进制)。hex(int(ff))
0赞 relent95 11/8/2023
你的设计将十六进制字符串转换为浮点数是一个糟糕的主意。别这样。

答:

0赞 yingw 11/9/2023 #1

感谢 @mark-tolonen 指向 float64 的 53 位和舍入的指针。对于我尽最大努力映射以恢复自动转换问题的用例,以下代码就足够了

bb = bin(int(ff))
hex(int(bb[2:53],2)) # 51 bits, see below
# 0x6de517a18f003

更多解释:

十六进制由 4 位 (2^4 = 16) 表示,因此在查看二进制位置时

  • 0..3 - 第一个十六进制值
  • 4..7 - 下一个十六进制值
  • ...
  • 48..51 - 最后完成
  • 52..56 - 这个将是不完整的,因为我们只得到 53 位的精度

由于字符串前面有 '0b',我们取 2:(2+51),这就是我们得到的方式bb[2:53]

评论

0赞 Mark Ransom 11/9/2023
请注意,在 int 到 float 转换中发生的舍入可能会抛弃您从此过程中返回的 int。
1赞 Mark Ransom 11/9/2023
对于我所说的具体示例,请尝试 .hh = 0x3fffffffffffff
0赞 yingw 11/10/2023
感谢您提出这个边缘情况,我看不出有一个简单的方法可以解决...
0赞 Mark Ransom 11/10/2023
我也看不出有什么办法可以解决它,否则我会提到它。您的数据已经因转换为浮点数而不可挽回地损坏。我只是想提醒你注意这个问题,这样你就可以有一个处理失败的计划。