将float数组转换为little / big endian

时间:2013-05-08 21:49:29

标签: python unit-testing networking network-programming endianness

我正在生成用于模拟网络的单元测试的二进制文件。通过网络发送的一些数据是Little Endian或Big Endian模式,我想用存根和创建二进制文件来模拟这些数据。

因此,换句话说,我不会使用活动网络进行单元测试,而是生成包含我期望从网络套接字获得的等效数据的二进制文件。

我使用Python 2.7生成字节数组并将它们保存到文件中,但是我将浮点数组转换为小端模式时遇到了问题。

from array import array
output_file = open(r"C:\temp\bin.dat", "wb")
float_array = array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72])
float_array.byteswap(); #This doesn't convert it to little endian!
float_array.tofile(output_file)
output_file.close()

所以我想知道是否有人知道如何操作数组,这样当我float_array.tofile()时,它会以小/大端模式写二进制数据。

此代码提供以下输出:

Val = 8.6184E-41
Val = 0.0
Val = 4.1897916E-8
Val = 4.172325E-8
Val = -1.9212016E-29
Val = -490.3153
Val = -1.5834067E-23

哪个与想要的array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72])

不符

当我注释掉byteswap方法时,我会得到以下内容

Val = 0.0
Val = 1.875
Val = 4.172325E-8
Val = 1.9
Val = 1.9023206E17
Val = 1.67
Val = -1.5881868E-23

但是,在实际网络模式下,它运行良好。但这对单元测试没有帮助!

1 个答案:

答案 0 :(得分:3)

您向我们展示的代码是创建一个8(64位)双精度数组。你没有告诉我们的代码是回读一个4(32位)浮点数组。除了这个问题,它们都是正确的。

解决方法是在这里使用'f''d',以便您的阅读和写作相匹配。

验证:

>>> float_array = array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72])
>>> float_array.byteswap()
>>> s = float_array.tostring()
>>> new_float_array = array('f')
>>> new_float_array.fromstring(s)
>>> new_float_array
array('f', [8.618405945136922e-41, 0.0, 4.189791624753525e-08, 4.17232506322307e-08, -1.9212016359104883e-29, -490.3153076171875, -1.5834066576694083e-23, -6.352746725754018e-23, -360092172025856.0, -5.209340637631123e-17, -1.5917267736367743e-23, -6.352746725754018e-23, -2.141351348326541e+32, 4.89745031096063e-14, 2.950574046482335e-41, 0.0])

看起来很熟悉?现在取出byteswap

>>> float_array = array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72])
>>> s = float_array.tostring()
>>> new_float_array = array('f')
>>> new_float_array.fromstring(s)
>>> new_float_array
array('f', [0.0, 1.875, 4.17232506322307e-08, 1.899999976158142, 1.902320558192722e+17, 1.6699999570846558, -1.5881868392106856e-23, 2.5562498569488525, 9.121204334167384e-33, 1.5049999952316284, -1.5881868392106856e-23, 1.8874999284744263, -71.68000030517578, 1.84499990940094, 0.0, 3.28125])

请注意,我使用的是tostring / fromstring,而不是tofile / fromfile,这意味着我没有指定计数。但是如果你指定一个8的计数,你显然会将前4个双打作为8个浮点数。如果你然后将它们格式化为输出:

>>> print '\n'.join('Val = {}'.format(val) for val in new_float_array[8])
Val = 8.6184E-41
Val = 0.0
Val = 4.1897916E-8
Val = 4.172325E-8
Val = -1.9212016E-29
Val = -490.3153
Val = -1.5834067E-23