python位运算and编码 剑指Offer

python里面的负数直接将其和0xffffffff进行与(&)操作即可得到其补码:

def func(n):
    if n < 0:
        n = n & 0xffffffff

剑指Offer

题目

输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        # write code here
        """
        补码:正数不变,负数是整数的反码+1
        2的二进制:
        -2 补码:
        """
        count = 0
        for i in range(32):
            mask = 1 << i
            if n & mask != 0:
                count += 1
        return count
# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        ans = 0
        if n < 0: n = n & 0xffffffff
        while n:
            ans += 1
            n = n & (n-1)
        return ans

存储方式

Python 对于负数的存储方式和 c++/c/java 不一样
1、在 python 里面,负数的存储方式

a = bin(-3)
print(a)
# -0b11
 
a = bin(3)
print(a)
# 0b11
 
b = bin(-3 & 0xffffffff)
print(b)
# 0b11111111111111111111111111111101
 
c = bin(0xfffffffd)
print(c)
# 0b11111111111111111111111111111101

也就是说:

Python 中的整型是补码形式存储的
Python 中 bin 一个负数(十进制表示),输出的是它的原码的二进制表示加上个负号
Python 中 bin 一个负数(十六进制表示),输出的是对应的二进制表示。(注意此时)


所以为了获得负数(十进制表示)的补码,需要手动将其和十六进制数 0xfffffffd 进行按位与操作,得到结果也是个十六进制数,再交给 bin() 进行输出,得到的才是你想要的补码表示。

2、但是在c/c++/java里面负数都是以补码的形式进行存储的,《计算机原理》显示,计算机内部采用2的补码(Two’s Complement)表示负数。

3、这就出现了在Python里面需要将负数和0xffffffff进行与操作,来去掉负数前面的负号,可以理解为超过32位的东西就不进行考虑了,这进行与操作的具体步骤是:如果是正数,直接与;如果是负数,先去掉最前面的负号,再取反,再加1,再进行与操作。从而得到负数的补码。

参考:https://www.runoob.com/w3cnote/python-negative-storage.html
https://blog.csdn.net/weixin_44414948/article/details/114809621

猜你喜欢

转载自blog.csdn.net/caicai0001000/article/details/115190701