首页 > 技术文章 > 【编程1】求二进制数中1的个数——引发的问题

jianfeijiang 2016-05-16 17:52 原文

《编程之美》书中有这样的一道问题“求二进制数中1的个数”

题目:对于一个字节(8bit)的无符号整形变量,求其二进制中“1”的个数,要求算法的执行效率尽可能高。

我使用java语言处理:输出结果是3

public class Count {
    public static int Count(byte d){
        int num = 0;
        while (d != 0) {
            d &= (d-1);//比较1的个数
            num++;            
        }
        return num;
    }
    public static void main(String[] args) {
        byte b = 7;
        System.out.println(Count(b));
    }
}

本文的问题不在于题目的要求上,而是要清楚java语言中的位数信息。“一个字节(8bit)的无符号整形变量”这个在java中如何表示?

java提供了一个byte数据类型,并且是基本类型。java byte是做为最小的数字来处理的,因此它的值域被定义为-128~127。

 

不要误用java中的int类型

public static void main(String[] args) {
    int d = -7;
    System.out.println(Integer.toBinaryString(d));
}

结果是:11111111111111111111111111111001

可以看到是32位的补码表示。

其原码:10000000000000000000000000000111

其反码:11111111111111111111111111111000

其补码:11111111111111111111111111111001 就是我们看到的输出

原码:

符号位用0表示正号,用1表示负号,数值一般用二进制形式表示

反码:

机器数的反码可由原码得到。如果机器数是正数,则该机器数的反码与原码一样;如果机器数是负数,则该机器数的反码是对它的原码(符号位除外)各位取反而得到的。

补码

机器数的补码可由原码得到。如果机器数是正数,则该机器数的补码与原码一样;如果机器数是负数,则该机器数的补码是对它的原码(除符号位外)各位取反,并在未位加1而得到的。

其关系如下:

正数:原码=反码=补码,并用原码表示;

负数:反码=~原码(除符号位)、补码=反码+1,用补码表示;

 

推荐阅读