二进制补码符号扩展 Python?

7

我想知道在Python中是否有一种方法可以像C/C++中一样进行二进制补码符号扩展,使用标准库(最好在位数组上)。

C/C++:

// Example program
#include <iostream>
#include <string>

int main()
{
    int x = 0xFF;
    x <<= (32 - 8);
    x >>= (32 - 8);
    std::cout << x;
    return 0;
}

这是我写的一个Python函数,经过测试已经实现了相同的功能。我只是想知道是否有一种内置的(或更快的)方法来完成这个任务:

def sign_extend(value, bits):
    highest_bit_mask = 1 << (bits - 1)
    remainder = 0
    for i in xrange(bits - 1):
        remainder = (remainder << 1) + 1

    if value & highest_bit_mask == highest_bit_mask:
        value = (value & remainder) - highest_bit_mask
    else:
        value = value & remainder
    return value

https://dev59.com/qHI-5IYBdhLWcg3w8NSB - wwii
啊,之前不知道为什么没看到。谢谢你指出来。 - Vasu
这是用于字符串转换的。 - wwii
1个回答

19
以下代码与您的函数产生相同的结果,但稍微更短。另外,显然,如果您要将其应用于大量数据,则可以预先计算两个掩码。
def sign_extend(value, bits):
    sign_bit = 1 << (bits - 1)
    return (value & (sign_bit - 1)) - (value & sign_bit)

非常聪明的确实 - Sven
有没有一个小例子可以演示如何使用它?sign_extend(0xFF, 32)产生的结果是255,这与0xFF相同。我期望它应该是0xFFFFFFFF。 - nurabha
sign_extend(10,4) 产生 -6,这是无符号值为10时用4位表示的有符号等效(2's complement)值。 sign_extend(10,5) 产生值10或'0b1010'。我原以为它会产生'0b11010',而不是值26。这对我来说不是符号扩展操作,而是给定位数中值的有符号表示。 - nurabha
该函数的目的是将固定宽度整数的符号位扩展为Python int,而不是执行否定操作。您在使用sign_extend(10, 4)时看到的明显否定是因为10实际上无法表示为4位二进制补码值。但是,10可以表示为5位二进制补码值,并且它的符号位是--等待它--零。这个函数正确地进行了扩展。现在,如果您输入26、5,那么,是的,您会看到一个负数出现。 - Patrick Maupin
@nurabha 你应该这样调用:sign_extend(0xFF, 8)。bits参数是输入中的位数;输出始终是Python有符号整数的大小。 - Brian A. Henning

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接