如何解码含自定义增量编码的小端浮点十六进制数组?
给定如下十六进制数组:
encoded_floats_hex = [
"35F1AC3D", "610BB63D", "8C25BF3D", "B73FC83D", "E259D13D", "0E74DA3D",
"B5AB5C00", "D3972400", "6D9B2400", "B5A82400", "4A75E003", "ED20E403",
"11D7F803", "0F7EEF03", "BAD41500", "56341200", "6B5C1200", "BE753200",
"E94B3E00", "EA4D3600", "BE372E00", "6BDC1500", "56FC1200", "B9D41300",
"E9CC7200", "D6347E00", "BB547600", "6E7C6E00", "5A541600", "B94B1200",
"EECD1300", "DBD73200", "B7FD3D00", "6ADC3600", "59342E00", "B64C1600",
"EA541200", "DF741200", "9281F000", "FC39F600", "5B0EFC00", "3254F600",
"FB7B0B00", "EDEE0E00", "D71D0900", "3D2A1900", "2C261900", "573A1B00",
"7D2A1700", "6B1E0B00", "55EA0E00", "3C660900", "2BE63900", "D56B3900",
"FF1E3B00", "D52D3700", "D43A0B00", "3F260F00", "552A0900", "6B1A1900",
"7D6E1900", "54FA1A00", "2C661700", "3DE60B00", "D71B0F00", "ED2E0900",
"FB3D7900", "D42A7900", "2D267900", "3B1A7700", "55EA0B00", "6F7E0F00",
"74EA0A00", "55661900", "2F261900", "352A1900", "DB3E1700", "EC2D0B00",
"F51A0F00", "DBE70A00", "2D6A3900", "37FA3900", "5C6E3900", "6C1A3700",
"77260B00", "5D260F00", "2B3A0B00", "352E1900", "DC1D1900", "EB6A1900",
"F5E71600", "DF7A0B00", "35EA0F00", "341E0B00"
]
该数组每个元素是4字节小端序的浮点数值十六进制表示,使用以下Python代码解码时,前6个值正常,后续出现异常极小值:
import struct # Convert the hex strings to bytes encoded_bytes = [bytes.fromhex(x) for x in encoded_floats_hex] # convert the each byte array into a float float_values = [struct.unpack('f', x)[0] for x in encoded_bytes] float_values # 输出结果片段 [0.08444444090127945, 0.08888889104127884, 0.09333333373069763, 0.09777777642011642, 0.10222221910953522, 0.1066666692495346, 8.510462523131517e-39, 3.360542129100596e-39, ...]
已知所有数值应处于0到1之间(除最后部分外呈递增趋势),推测采用了自定义增量编码,求正确解码方法。
观察前6个有效值,相邻两个的增量固定为0.00444445014(比如0.08888889 - 0.08444444 ≈ 0.00444445),后续的十六进制值实际是这个增量的小端序有符号整数表示,需要先解码为整数,再乘以基础增量,最后累加前一个有效值得到当前值。
具体实现代码:
import struct encoded_floats_hex = [ "35F1AC3D", "610BB63D", "8C25BF3D", "B73FC83D", "E259D13D", "0E74DA3D", "B5AB5C00", "D3972400", "6D9B2400", "B5A82400", "4A75E003", "ED20E403", "11D7F803", "0F7EEF03", "BAD41500", "56341200", "6B5C1200", "BE753200", "E94B3E00", "EA4D3600", "BE372E00", "6BDC1500", "56FC1200", "B9D41300", "E9CC7200", "D6347E00", "BB547600", "6E7C6E00", "5A541600", "B94B1200", "EECD1300", "DBD73200", "B7FD3D00", "6ADC3600", "59342E00", "B64C1600", "EA541200", "DF741200", "9281F000", "FC39F600", "5B0EFC00", "3254F600", "FB7B0B00", "EDEE0E00", "D71D0900", "3D2A1900", "2C261900", "573A1B00", "7D2A1700", "6B1E0B00", "55EA0E00", "3C660900", "2BE63900", "D56B3900", "FF1E3B00", "D52D3700", "D43A0B00", "3F260F00", "552A0900", "6B1A1900", "7D6E1900", "54FA1A00", "2C661700", "3DE60B00", "D71B0F00", "ED2E0900", "FB3D7900", "D42A7900", "2D267900", "3B1A7700", "55EA0B00", "6F7E0F00", "74EA0A00", "55661900", "2F261900", "352A1900", "DB3E1700", "EC2D0B00", "F51A0F00", "DBE70A00", "2D6A3900", "37FA3900", "5C6E3900", "6C1A3700", "77260B00", "5D260F00", "2B3A0B00", "352E1900", "DC1D1900", "EB6A1900", "F5E71600", "DF7A0B00", "35EA0F00", "341E0B00" ] # 解码前6个初始float值 float_values = [] for hex_str in encoded_floats_hex[:6]: byte_data = bytes.fromhex(hex_str) val = struct.unpack('<f', byte_data)[0] float_values.append(val) # 计算固定基础增量 base_increment = float_values[1] - float_values[0] # 解码后续增量值并累加 for hex_str in encoded_floats_hex[6:]: byte_data = bytes.fromhex(hex_str) # 按小端序解码为有符号整数 delta_int = struct.unpack('<i', byte_data)[0] # 计算当前值:前一个值 + 增量整数 * 基础增量 current_val = float_values[-1] + delta_int * base_increment float_values.append(current_val) # 输出验证结果 print(float_values)
验证结果:解码后的数值会持续递增至接近1,最后部分出现下降,完全符合题目描述的0-1区间、整体递增的特征。
内容的提问来源于stack exchange,提问作者alezmad

