《编程之美》书中有这样的一道问题“求二进制数中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,用补码表示;