a 和b(十六进制)下方,表示二进制补码有符号二进制数。 例如:
a = 0x17c7cc6e
b = 0xc158a854
现在我想知道以 10 为基数的 a 和 b 的符号表示。觉得问这个很傻。我不关心额外的图书馆,但答案应该简单明了。背景:a 和 b 是从 UDP 数据包中提取的数据。我无法控制格式。所以请不要给我一个假设我可以事先更改这些变量格式的答案。
我已经将 a 和 b 转换为以下内容:
aBinary = bin(int(a, 16))[2:].zfill(32) => 00010111110001111100110001101110 => 398969966
bBinary = bin(int(b, 16))[2:].zfill(32) => 11000001010110001010100001010100 => -1051154348
我正在尝试做这样的事情(不起作用):
if aBinary[1:2] == 1:
aBinary = ~aBinary + int(1, 2)
在 python 中执行此操作的正确方法是什么?
ctypes ?
>>> import ctypes
>>> a = 0x17c7cc6e
>>> ctypes.c_int32(a).value
398969966
>>> b = 0xc158a854
>>> ctypes.c_int32(b).value
-1051154348
def s32(value):
return -(value & 0x80000000) | (value & 0x7fffffff)
将此应用于您的价值观:
>>> s32(a)
398969966
>>> s32(b)
-1051154348
此函数的作用是对值进行符号扩展,以便使用正确的符号和值正确解释它。
Python 有点棘手,因为它使用任意精度的整数,因此负数被视为有无限系列的前导 1 位。例如:
>>> bin(-42 & 0xff)
'0b11010110'
>>> bin(-42 & 0xffff)
'0b1111111111010110'
>>> bin(-42 & 0xffffffff)
'0b11111111111111111111111111010110'
>>> import numpy
>>> numpy.int32(0xc158a854)
-1051154348
In [232]: b = 0xc158a854
In [233]: if b >= 1<<31: b -= 1<<32
In [234]: b
Out[234]: -1051154348L
这里的 L 表示 Python 2 已经切换到 long 处理值;它通常并不重要,但在这种情况下表明我一直在使用此安装的公共 int 范围之外的值。从UDP包等二进制结构中提取数据的工具是
struct.unpack;如果你只是告诉它你的值首先是有符号的,它会产生正确的值:
In [240]: s = '\xc1\x58\xa8\x54'
In [241]: import struct
In [242]: struct.unpack('>i', s)
Out[242]: (-1051154348,)
假设二进制补码表示;一个的补码(例如 UDP 中使用的校验和)、符号和大小或 IEEE 754 浮点数是一些不太常见的数字编码。
>>> h = 0xc158a854
>>> int.from_bytes(bytes.fromhex(hex(h)[2:]), byteorder='big', signed=True)
-1051154348
2^31-1 = 0x7fffffff(所有正位)
你甚至可以这样做,n - ((n & 0x80000000)
<<1) to subtract the msb value twice
或者最后有 (n & 0x7fffffff) | -(n & 0x80000000) 只是合并负位,而不是减去
def signedHex(n): return (n & 0x7fffffff) | -(n & 0x80000000)
signedHex = lambda n: (n & 0x7fffffff) | -(n & 0x80000000)
value=input("enter hexa decimal value for getting compliment values:=")
highest_value="F"*len(value)
resulting_decimal=int(highest_value,16)-int(value,16)
ones_compliment=hex(resulting_decimal)
twos_compliment=hex(r+1)
print(f'ones compliment={ones_compliment}\n twos complimet={twos_compliment}')