一些语言,如Java,Verilog都有按位逻辑(<<,>>)和算术移位(<<<,>>>)操作符。
对于无符号值,逻辑移位和算术移位具有相同的操作。假设8‘b 11000101是8位无符号数197的二进制表示,那么
8'b11000101 >> 2 => 8'b00110001
8'b11000101 >>> 2 => 8'b00110001
8'b11000101 << 2 => 8'b00010100
8'b11000101 <<< 2 => 8'b00010100对于有符号值,只有算术和逻辑左移位操作是相同的,但是算术右移位导致符号扩展。假设8‘b 11000101是8位有符号数字-59的二进制表示,那么
8'b11000101 >> 2 => 8'b00110001
8'b11000101 >>> 2 => 8'b11110001
8'b11000101 << 2 => 8'b00010100
8'b11000101 <<< 2 => 8'b00010100Python只有逻辑移位操作符,但没有算术移位运算符。那么,如何在python中实现签名值和无符号值的算术右移呢?
发布于 2020-11-24 12:59:46
只有逻辑移位操作符,但没有算术移位运算符。那么,如何在python中实现签名值和无符号值的算术右移呢?
Python实际上只有算术移位操作符:
n的2乘乘幂n完全相同,两者均为负值,n的幂,然后四舍五入到0,而负值表现为在最重要的位侧有无限串的1位,这是两个负数的补码表示的副作用。这转化为一个单一的数学等价:用一个正的积分量将一个整数右移为2除以Math.floor(value / 2**n)的平方,并将结果除以负无穷大。
如果您想模拟负值的无符号右移(在java和javascript中可用),则必须使用所考虑的固定位数将负值转换为正数。将给出预期价值的权利转移:
x = -1
x32 = x & 0xffffffff # convert to 32-bit unsigned value
x >> 8 # produces -1
x32 >> 8 # produces 0x00ffffff发布于 2021-01-26 19:36:39
我认为你的问题的答案取决于你是如何储存你的数字。如果希望0b11000101表示-59,则需要在执行移位之前以某种方式指定位长。请注意,Python对否定的二进制表示不是以2的补语格式表示的:
>>> bin(59)
'0b111011'
>>> bin(-59)
'-0b111011'因此,如果-0b111011适用于您的目的,那么您可以执行chqrlie的答案中指定的算术右移。
但是,如果您需要您的结果以2的补码格式表示,即需要将0b11000101算术右移2来计算为字面上的0b11110001,那么下面的函数应该适用于您:
# x is an n-bit number to be shifted m times
def sra(x,n,m):
if x & 2**(n-1) != 0: # MSB is 1, i.e. x is negative
filler = int('1'*m + '0'*(n-m),2)
x = (x >> m) | filler # fill in 0's with 1's
return x
else:
return x >> m这基本上是执行规则的右移,但如果数字是负数(2的补码格式,具有指定的位长),则用1填充前导零。
示例:
sra(0b11000101, 8, 2) -> 0b11110001
sra(0x805a6cf3, 32, 0x10) -> 0xffff805a
sra(0x705a6cf3, 32, 0x10) -> 0x0000705a发布于 2020-11-23 08:07:55
不是python编码器,但我通常这样解决这个问题:
x = (x>>1)|(x&80); // 8bit
x = (x>>1)|(x&8000); // 16bit
x = (x>>1)|(x&80000000); // 32bit因此,只需将原始MSb的x复制到由位移位创建的空间中即可。然而,这将只适用于轮班1位。为了获得更多信息,您需要这样做:
if (x<0) x = (x>>2)|0xC0; else x = x>>2; // 8bit
if (x<0) x = (x>>2)|0xC000; else x = x>>2; // 16bit
if (x<0) x = (x>>2)|0xC0000000; else x = x>>2; // 32bit
if (x<0) x = (x>>3)|0xE0; else x = x>>3; // 8bit
if (x<0) x = (x>>3)|0xE000; else x = x>>3; // 16bit
if (x<0) x = (x>>3)|0xE0000000; else x = x>>3; // 32bit
if (x<0) x = (x>>4)|0xF0; else x = x>>4; // 8bit
if (x<0) x = (x>>4)|0xF000; else x = x>>4; // 16bit
if (x<0) x = (x>>4)|0xF0000000; else x = x>>4; // 32bit
if (x<0) x = (x>>5)|0xF8; else x = x>>5; // 8bit
if (x<0) x = (x>>5)|0xF800; else x = x>>5; // 16bit
if (x<0) x = (x>>5)|0xF8000000; else x = x>>5; // 32bit
...您可以为掩码创建LUT。
LUT8[8]=
{
0x00,
0x80,
0xC0,
0xE0,
0xF0,
0xF8,
0xFC,
0xFE,
}
if (x<0) x = (x>>k)|LUT8[k&7]; else x = x>>k; // 8bitk位移位的掩码仅仅是包含来自MSb的k 1的数字,其余的是二进制的零。
还有更简单的解决方案(代价是两次否定),如下所示:
if (x<0) x = -((-x)>>k); else x = x>>k;https://stackoverflow.com/questions/64963170
复制相似问题