我必须将给定的16位整数转换为两个8位整数,然后将它们作为输出并用作输出,其中它们将取两个8位整数并将它们重新组合为16位输入(不幸的是我无法控制) )。我的解决方案有效,但感觉不洁净。对于粗数我移位原始数字,对于精细数字,我看它模数为256。
那么我应该对粗数进行分区,还是应该将最低8位用于精确数字(如果是这样的话?)?
或者我疯了并且使用两种不同的方法来分割数字不是问题吗?
def convert(x):
''' convert 16 bit int x into two 8 bit ints, coarse and fine.
'''
c = x >> 8 # The value of x shifted 8 bits to the right, creating coarse.
f = x % 256 # The remainder of x / 256, creating fine.
return c, f
答案 0 :(得分:12)
我愿意
c = (x >> 8) & 0xff
f = x & 0xff
更安全,见例如。
>>> (10303 >> 8) & 0xff
40
>>> (1030333333 >> 8) & 0xff
163
>>> (1030333333 >> 8)
4024739
因为在python中你不能控制如果数字是16位,你必须强制它最多16位值。如果您确定具有16位值,则不需要这样做,但这样功能更通用,并且无论容器包含什么,您都只能对16位值感兴趣。
答案 1 :(得分:7)
在python中,bit-fiddling没有任何特别的优势,所以我会选择:
c, f= divmod(your_number, 256)
编辑:为了使你的意图对于两个挑战的源查看器(如果存在这样的野兽)更加明显,你可以用更多色彩替代品替换普通256
,例如{{ 1}},1<<8
,2**8
或0x100
。窥孔优化器从2.5开始的常量折叠确保它们中的任何一个完全相同,就像使用0400
一样(我显然在谈论前两个替代方案,它们是评估为256
的表达式;后两个是常量256
)。
256
答案 2 :(得分:2)
你应该保持一致,如果操作的意图是算术的,使用模数和除法,如果它仅用于原始位操作,则使用移位和掩码。
答案 3 :(得分:1)
你说你正在使用这些数字作为输出,这表明它们将在某些时候被转换为字符串。考虑到这一点,我建议你看看struct
module,它正是为了这种事情而设计的(将数字打包成二进制数据字符串)。作为奖励,您可以在x
大于65535的情况下获得内置错误检查(这样,如果程序中的某些内容非常糟糕,您将获得例外)。例如,
s = struct.pack('>H', x)
相当于
if x > 65535:
raise struct.error(...)
c, f = convert(x)
s = chr(c) + chr(f) # big-endian (network) byte ordering
如果需要其他字节排序,可以编写
s = struct.pack('<H', x)
如果您要同时转换一大堆数字,struct.pack
可以成群进行转换:
x = [10333, 10475, 3021, ...] # for example
s = struct.pack('>' + 'H' * len(x), *x)
答案 4 :(得分:0)
如果你在不同的地方使用这两个数字的两半,我建议你有两个独立的功能,但如果你要在同一个地方使用它们,一个功能也可以正常工作。
有几种正确的方法来分割数字,所以最终归结为个人偏好。 只要您传入最多16位长的数字,您的代码就可以正常工作。 (这可能不是什么大问题,但你应该知道它)
答案 5 :(得分:0)
我会使用bitwise&amp;而不是 %。对于短整数,这些天可能几乎没有什么区别,但在更广泛的视野中,&amp;运营商可能更有效率。
关于%如何处理负数可能存在一些问题,但我怀疑这是否与此相关。