Chr*_*ris 5 c python floating-point binary ieee-754
我正在解码一个二进制文件,它有四个字节表示的十进制数字,小端.例如,94 53 F0 40代表7.510202.不幸的是,Python给了我7.51020240784.
当我尝试解析这些数据时unpack("<f",sampledata)[0],由于Python存储值的方式,我没有得到原始数据的精确表示(有关更多信息,请参阅http://bugs.python.org/issue4114).
不幸的是,我确实需要获得完全相同的表示 - 无论有关浮点数的不准确性的讨论,因为我需要将这些值写入文本文件,其初始值与最初写入二进制文件的位数相同.
如果可能的话,我宁愿坚持使用Python,但如果有必要,我很乐意在C中实现解决方案.我不能简单地截断unpack函数返回的原因是我不能保证原始float有多少小数位,例如0C 02 0F 41根据我的十六进制编辑器代表8.938,原始二进制文件只有3个小数位.
为了清楚起见,我需要将四个十六进制字节作为输入,并输出文本/ ASCII或IEEE 32位浮点数的数字表示,其具有与创建者所预期的相同的小数位数.文件.输出我将用于创建原始二进制数据文件的CSV,而不是用于实际执行任何计算.
有什么建议?
例:
from __future__ import print_function
from struct import *
print("Should print 7.510202")
hexbytes = b"\x94\x53\xF0\x40"
# 01101001 11001000 11110001 01000000
# should print 7.510202
print(unpack("<f",hexbytes)[0])
Run Code Online (Sandbox Code Playgroud)
4字节IEEE格式浮点数保持大约7位数.你想要做的是将结果四舍五入unpack到总共7位数.从那里,从float到string的正常Python转换将隐藏你的所有浮点数.
def magnitude(x):
return 0 if x==0 else int(math.floor(math.log10(abs(x)))) + 1
def round_total_digits(x, digits=7):
return round(x, digits - magnitude(x))
>>> round_total_digits(struct.unpack('<f', '\x94\x53\xF0\x40')[0])
7.510202
>>> round_total_digits(struct.unpack('<f', '\x0C\x02\x0F\x41')[0])
8.938
>>> x = struct.unpack('<f', struct.pack('<f', 12345.67))[0]
>>> x
12345.669921875
>>> round_total_digits(x)
12345.67
Run Code Online (Sandbox Code Playgroud)
请注意,如果您的数字不是来自直接转换十进制数,而是计算结果,则可能会降低总体准确性.但不是很多.