提问人:yingw 提问时间:11/8/2023 最后编辑:yingw 更新时间:11/9/2023 访问量:48
将大整数 (uint64+) 转换为十六进制
Converting large integer (uint64+) into hex
问:
在将内容导入 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 中的浮点实现。
答:
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
我也看不出有什么办法可以解决它,否则我会提到它。您的数据已经因转换为浮点数而不可挽回地损坏。我只是想提醒你注意这个问题,这样你就可以有一个处理失败的计划。
评论
hh
包含 64 个十六进制数字,即 256 位。浮点数只有 64 位。float.fromhex(hh)
返回,所以声明是假的。 给出了这个数字,但正如其他人所说,浮点数是 64 位,并且该数字被截断了。TypeError: bad argument type for built-in operation
ff = 4.9706871569187424e+76 # same as calling float.fromhex(hh)
float(hh)
hex(int(ff))