如标题所示,JavaScript 中有一个特定的运算符
>>>
。例如,在 JavaScript 中我们将得到以下结果:
(-1000) >>> 3 = 536870787
(-1000) >> 3 = -125
1000 >>> 3 = 125
1000 >> 3 = 125
那么有没有某种方法或运算符可以代表这个
>>>
?
没有内置的运算符,但您可以自己轻松模拟
>>>
:
>>> def rshift(val, n): return val>>n if val >= 0 else (val+0x100000000)>>n
...
>>> rshift(-1000, 3)
536870787
>>> rshift(1000, 3)
125
以下替代实现消除了对
if
的需要:
>>> def rshift(val, n): return (val % 0x100000000) >> n
不,没有。 python 中的右移是算术运算。
这是 aix 的答案的衍生内容。如果您向其提供正值,则正常的右移运算符将起作用,因此您实际上正在寻找从有符号到无符号的转换。
def unsigned32(signed):
return signed % 0x100000000
>>> unsigned32(-1000) >> 3
536870787L
尝试通过用 0x100000000 掩码来翻转负数的符号位从根本上是错误的,因为它对字长做出了艰难的假设。在我作为程序员期间,我使用过 24、48、16、18、32、36 和 64 位数字。我还听说过以奇数长度工作的机器,例如 37 和其他使用补码而不是补码算术的机器。除了数字是二进制之外,你对数字的内部表示所做的任何假设都是危险的。
即使二元假设也不是绝对安全的,但我认为我们会允许这种情况。 :)
您需要记住,如果数字为负数,则设置最高位,并且每次向右移位时,您也需要设置最高位。
这是我的实现:
def rshift(val, n):
s = val & 0x80000000
for i in range(0,n):
val >>= 1
val |= s
return val
无需模数即可工作的解决方案:
>>> def rshift(val,n): return (val>>n) & (0x7fffffff>>(n-1))
这是有效的,因为 7fffffff 是一个正数,右移会在左侧添加零。
您还可以使用楼层划分:
def rshift(val, n):
if val > 0:
return val >> n
return val // -(2^n)
这不是一种有效的方法,但效果正如预期的那样
def _toBinary(x):
x=int(x)
binary = []
while x > 0:
binary.append(str(x%2))
x=int(x/2)
return "".join(binary[::-1])
def _fromBinary(xs):
ans = 0
for i,x in enumerate(xs[::-1]):
if x == '1':
ans += 2**i
return ans
def leftLogicalShift(x,n=1):
if not type(x) == int:
return x
xs = _toBinary(x)
xs = [x for x in xs]
for _ in range(n):
xs.pop(0)
xs.append('0')
return _fromBinary("".join(xs))
def rightLogicalShift(x,n=1):
if not type(x) == int:
return x
xs = _toBinary(x)
xs = [x for x in xs]
for _ in range(n):
xs.pop()
xs.insert(0,'0')
return _fromBinary("".join(xs))
def leftArithmeticShift(x,n=1):
return leftLogicalShift(x,n)
def rightArithmeticShift(x,n=1):
if not type(x) == int:
return x
xs = _toBinary(x)
xs = [x for x in xs]
for _ in range(n):
tmp = xs[0]
xs.pop()
xs.insert(0,tmp)
return _fromBinary("".join(xs))
lls = leftLogicalShift(10,2)
print(lls) # 8
rls = rightLogicalShift(10,2)
print(rls) # 2
las = leftArithmeticShift(10,2)
print(las) # 8
ras = rightArithmeticShift(10,2)
print(ras) # 14
参考资料:
投票最高的答案对 val 产生错误的结果 < 0 and n == 0! Here is a correction.
def rshift(val, n):
if (val >= 0): return val >> n
elif (n == 0): return val
else: return (val + 0x10000000) >> n
>>> rshift(-1, 0)
-1
我认为逻辑右二进制移位在Python中不能直接使用。相反,您可以在 Python 中使用 Javascript,如下所示:
import js2py
rshift = js2py.eval_js('function $(a, b){ return a >>> b}')
print (rshift(244, 324)) #15