gpt4 book ai didi

python - 在 python 中的二进制运算中否定整数的好方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-04 03:13:30 30 4
gpt4 key购买 nike

根据我读到的关于 the binary representation of integers 的内容,第一位是符号(正或负)。

假设我们有一个整数 x = 5sys.getsizeof(x)返回 28 (即 28 位的二进制表示)。

现在我正在尝试将第一位翻转为 1通过使用 x|=(1<<27)但它返回 134217733 .

我只是想知道它是否需要是一些负数? (不是-5)

我这样做有什么问题吗?

最佳答案

您不能像您尝试的那样将 Python int 从正面切换到负面,只需在其表示中稍微翻转一下即可。您假设它存储在固定长度的二进制补码表示中。但是 Python 3 中的整数不是固定长度的位串,它们也不是以二进制补码表示形式存储的。相反,它们存储为 30 位或 15 位“数字”的可变长度字符串,符号单独存储(如 signed-magnitude representation )。因此,否定 Python int 的“最低级别”方法不是使用位操作,而是使用一元 - 运算符,它将切换其符号。 (有关 Python 3 源代码的详细信息,请参阅此答案的末尾。)

(我还应该提到 sys.getsizeof() 不会告诉您 int 中的位数。它会告诉您整数占用的内存字节数对象正在使用。这也不是实际存储数的字节数;这些字节中的大部分用于其他事情。)


您仍然可以在 Python 中使用二进制补码表示,方法是使用正 int 模拟固定长度的位串。首先,选择您想要的长度,例如 6 位。 (您可以轻松地选择更大的数字,例如 28 或 594。)我们可以定义一些有用的常量和函数:

BIT_LEN = 6
NUM_INTS = 1 << BIT_LEN # 0b1000000
BIT_MASK = NUM_INTS - 1 # 0b111111
HIGH_BIT = 1 << (BIT_LEN - 1) # 0b100000

def to2c(num):
"""Returns the two's complement representation for a signed integer."""
return num & BIT_MASK

def from2c(bits):
"""Returns the signed integer for a two's complement representation."""
bits &= BIT_MASK
if bits & HIGH_BIT:
return bits - NUM_INTS

现在我们可以像您一样做一些事情:

>>> x = to2c(2)
>>> x |= 1 << 5
>>> bin(x)
'0b100010'
>>> from2c(x)
-30

这表明在 6 位二进制补码表示中打开数字 2 的高位会将数字变为 -30。这是有道理的,因为 26-1 = 32,所以这个表示中的最小整数是 -32。并且 -32 + 2 = -30。


如果您对 Python 3 如何存储整数的细节感兴趣,可以查看 Objects/longobject.c在源代码中。特别是看 the function _PyLong_Negate() :

/* If a freshly-allocated int is already shared, it must
be a small integer, so negating it must go to PyLong_FromLong */
Py_LOCAL_INLINE(void)
_PyLong_Negate(PyLongObject **x_p)
{
PyLongObject *x;

x = (PyLongObject *)*x_p;
if (Py_REFCNT(x) == 1) {
Py_SIZE(x) = -Py_SIZE(x);
return;
}

*x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x));
Py_DECREF(x);
}

您可以看到它在正常情况下所做的只是取反整数对象的 Py_SIZE() 值。 Py_SIZE()只是对整数对象的 ob_size 字段的引用。当此值为0时,整数为0。否则,其符号为整数的符号,其绝对值为保存整数绝对值的数组中30位或15位数字的个数。

关于python - 在 python 中的二进制运算中否定整数的好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37135106/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com