【问题标题】:Python and integer representation (leading zeros issue)Python 和整数表示(前导零问题)
【发布时间】:2013-09-12 23:47:42
【问题描述】:

这类似于在编程 Stack Exchange 上提出的问题:https://softwareengineering.stackexchange.com/questions/158247/binary-representation-in-python-and-keeping-leading-zeros

基本上,我有一些我用十六进制记录的数字:

SOME_NUMBERS = (0xAABBCCDDEEFF, 0xAA55AA55AA55, 0xBEEF0000BEEF)

但是,Python 试图比我聪明并且想得太多,所以当我将值写入文件时,我会在我的十六进制编辑器中得到这个:

00 00 00 00 00 00 00 00 00 00 AA BB CC DD EE FF

在我看来,Python 将我的 48 位数字存储和写入为 64 位或 128 位数字。如何防止将前导零写入文件?相比之下,当使用numpy.random.bytes(6) 时,Python 会将值写入文件而没有前导零,所以我认为它应该能够做到这一点。想法?

【问题讨论】:

  • packing 数据和写入文件怎么样?
  • 请出示您的代码,我们(通常)不能盲目猜测问题。
  • en.wikipedia.org/wiki/Primitive_data_type#Integer_numbers 在 64 位平台上,Python 会将 0xAABBCCDDEEFF 作为 64 位整数存储在内存中(就像 0x1 甚至 0x0 一样),所以当你写出来你会得到 64 位,除非你自己明确地打包各个字节。

标签: python numpy integer binaryfiles


【解决方案1】:

关键是你如何打包数字。您可以写入单个字节 - 数字格式为 6 个字节是不寻常的。我发现以下内容适用于其中一个值:

import struct

outfile = 'output.dat'
fh = open(outfile, "wb")

var = struct.pack('6B', 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF)

fh.write(var)
fh.close()

如果您使用其他类型,例如 short、int 或 long(或它们的组合),您可能会遇到字节序问题。

【讨论】:

    【解决方案2】:

    如果您想将 48 位二进制值写入文件,您必须自己写入 6 个字节。没有这种长度的本机数字格式。使用struct 模块将值转换为字节:

    packed = struct.pack('>q', value) # 64 bits (8 bytes)
    f.write(packed[-6:])
    

    【讨论】:

      【解决方案3】:

      要解决我的问题,我必须做两件事:

      1) 切换到 Python 3 2) 使用 int.to_bytes()

      f = open(fileName, 'wb')
      for d in dataBuffer:
          if type(d) == int:
               f.write(d.to_bytes(6, byteorder='big'))
          else:
               f.write(d)
          f.close()
      

      我无法使用 struct.pack() 或 numpy.savetext(),因为我需要为 2000 个文件处理 10,000 个随机值。这似乎更容易,但我还必须让我的代码与 Python 3 一起工作。我了解到,Python 虽然试图变得聪明并为用户做事,但最终却把事情弄得一团糟,并增加了挫败感。

      【讨论】:

      • 不错!我不知道 python 3 有这个。奥托,对着你用拇指敲击的锤子大喊大叫可能会让你松一口气,但对你没有帮助。如果我从这类问题中学到了什么,那就是我自己的假设总是会受到质疑。但也许这对programmers.stackexchange.com 来说更重要:)
      【解决方案4】:

      您可以使用 np.savetxt 保存为文本:

      import numpy as np
      sn = np.array([0xAABBCCDDEEFF, 0xAA55AA55AA55, 0xBEEF0000BEEF])
      np.savetxt('testfile',sn,'0x%X')
      

      np.savetxt('testfile',sn,'%X') # without the '0x'
      

      【讨论】:

        【解决方案5】:

        如果您不想使用struct.pack,您可以通过屏蔽源整数的连续字节并使用chr 将它们转换为字节字符串来单独将字节写入文件:

        for shift in range(40, -1, -8):
            f.write(chr((d >> shift) & 0xff))
        

        但这基本上是 struct.pack 在引擎盖下(以及在 C 中)为你做的事情,所以你最好不要重新发明轮子。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多