位运算
在 Java 中怎么打印出一个 int 类型数字的二进制呢?int 数据类型是32位、有符号的以二进制补码表示的整数;long 数据类型是 64 位、有符号的以二进制补码表示的整数。
public class Bit_Operation {public static void print(int num) {for (int i = 31; i >= 0; i--) {System.out.print((num & (1 << i)) == 0 ? '0' : '1');}System.out.println();}public static void main(String[] args) {int num = 1;print(num); // '00000000000000000000000000000001'}}
上面的代码中我们实现了 print 函数,并且用它来打印了 int 类型 1 的二进制。仔细看上面的代码,我们发现了一个在前端中不怎么常用的符号 << 这是在干嘛?这个符号是左移动的意思。比如 int 类型的 1 它在计算机中是这样表示的:
todo img
public class Bit_Operation {public static void print(int num) {for (int i = 31; i >= 0; i--) {System.out.print((num & (1 << i)) == 0 ? '0' : '1');}System.out.println();}public static void main(String[] args) {int num = 1;print(num); // '00000000000000000000000000000001'print(num << 1); // '00000000000000000000000000000010'print(num << 2); // '00000000000000000000000000000100'print(num << 3); // '00000000000000000000000000001000'}}
从上面的代码可以看出:每次调用 << 这个符号,图中的 1 就会向左移动一位,它原来的位置进行补零操作(也就是用零来填补)。
左移不带符号,右移才带符号。一个数向左移动一位就得到的是这个数组的 2的n次方。一个整型不会把位数都用了,会保留最高位当做符号位。
int 类型的取值范围是 -2^31 - 2^31 - 1。向 C++ 中,无符号类型是 2^32 - 1。最高位为1表示是负数,最高位为0表示是非零数字。
前面我们说的都是正数类型的,下面我们来看下负数。
public class Bit_Operation {public static void print(int num) {for (int i = 31; i >= 0; i--) {System.out.print((num & (1 << i)) == 0 ? '0' : '1');}System.out.println();}public static void main(String[] args) {print(-1); // '11111111111111111111111111111111'}}
上面的代码我们打印了下 -1 用二进制表示的结果,可以看到输出全部是 1。这是为啥呢?
我们拿到一个 32 位的负数结果后怎么将它转换为对应的十进制呢?转换规则为:最高位为符号位,其余部分取反再加一。以 -1 举例,它用二进制表示如下:
11111111111111111111111111111111// 取反10000000000000000000000000000000// 再加一10000000000000000000000000000000+00000000000000000000000000000001// 得到的结果是100000000000000000000000000000001// 转成十进制-1
