欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

1.27 剑指offer 二进制中1的个数

程序员文章站 2022-07-15 14:29:02
...

位运算

在c 中左移也就是所说的逻辑移位,右端补0,而右移是算数移位,左端补齐的是最高位的符号位。
故负数左移,有可能变成正数,但负数右移,肯定还是负数。

  • 正数左移一位等价于乘以2
  • 负数左移一位不确定,因为符号位移出,可能变成正数,无等价运算
  • 正负数右移一位等价于除以2

补码

在计算机中,数值是按字节、按补码的形式存储,按位运算的。

数值用二进制原码表示时,最高位为符号位,正数为0、负数为1,位数不够用0补全。

如:9 和 -9 的原码分别为 0000 1001 和 1000 1001 。

用原码存储数值时,关于 0 和 -0 存在两种表示,分别为: 0000 0000 和 1000 0000 。

同一个数值,存在两种表示方法当然有问题,用补码便可解决。

关于补码,正数的补码同原码,负数的补码将原码的符号位不变、其余位取反、再加1。数值补码进行运算时,符号位参与运算

如:9 和 -9 的补码分别为: 0000 1001 和 1111 0111 。而0 和 -0 的补码均为: 0000 0000 。

补码运算可化减法为加法,方便运算。如: 9 - 9 = 9 + (-9),即(0000 1001) + (1111 0111) = 0000 0000 。

补码变回原码,依然是正数的原码同补码,负数的补码转原码需符号位不变、其余位取反、再加1,符号位参与运算。

题目

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

思路

找规律发现,把一个整数减去1,再和原始整数做与运算,会把该整数最右边的1变成0。
在 Python 程序中,当对一个负整数与其减 1 后的值按位求与,若结果为 0 退出,循环执行此过程。由于整型数可以有无限的数值精度,其结果永远不会是 0,在 Python 中,整型数是没有溢出的(overflow)。

在python中,负数和0xffffffff按位与之后变成一个无符号数,可减为0。

代码

    def NumberOf1(self, n):
        count = 0
        if n < 0:
            n = n & 0xffffffff
        while n:
            count += 1
            n = (n-1) & n
        return count
相关标签: 位运算