实际上我是通过阅读Android源码了解到一个int类型的值还能存储多个数据
本文就来随便聊一聊有关二进制的一些内容
在Java中int类型的数据占用4个字节,一个字节是8位,也就是32位,下面的所有内容都是用int型变量来实验的
位运算符
位运算是实现我在开头说的内容的关键点,虽然一开始学Java的时候就学过,但当初学习的时候确实没有重视实际开发过程中也没有用过所以对这些内容只能算是一知半解,下面来重新认识一些这个内容
运算符 | 描述 |
---|---|
& | 按位与,都是1则为1,否则为0 |
| | 按位或,都是0为0,否则为1 |
^ | 异或,相同为0 ,不同为1 |
~ | 非,按位取反,即1为0,0为1 |
<< | 按位左移 |
>> | 按位右移,不足时正数补0,负数补1 |
>>> | 按位右移,不足时补0 |
来看下具体效果,结合上面的说明就会有一个只管的了解
&
3&2=2
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000010
00000000 00000000 00000000 00000010
|
3|2=3
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000010
00000000 00000000 00000000 00000011
^
3^2=1
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000010
00000000 00000000 00000000 00000001
~
~3
00000000 00000000 00000000 00000011
11111111 11111111 11111111 11111100
<<
3<<2=12
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00001100
>>
3>>1=1
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000001-3>>1=-2
11111111 11111111 11111111 11111101
11111111 11111111 11111111 11111110
>>>
3>>>1=1
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000001-3>>>1=2147483646
11111111 11111111 11111111 11111101
01111111 11111111 11111111 11111110
>>和>>>的区别在负数的时候,我特意列了两个例子
10进制转二进制字符串
这个问题很好解决,Java就自带了转换的方法
Integer.toBinaryString();
还有转16进制以及8进制
Integer.toHexString();//转16进制字符串
Integer.toOctalString();//转8进制字符串
但是我有在网上看到一个转二进制的方法是利用位的移动和按位与来实现的
来源地址
关键内容我贴上来
public void binaryToDecimal(int n) {
for (int i = 31; i >= 0; i--)
System.out.print(n >>> i & 1);
}
一开始我还没看懂,毕竟这些东西不常用,所以我又去复习了上面的知识,才看懂这个代码的原理,将n循环右移将n的从高位到低位依次和1与,如果都是1就是1,有一个不是1就是0,1的二进制最低位肯定是1,其余位数为0,那么结果就是n的对应位数的值.我说的可能有点复杂,如果有不理解的可以将上面的步骤拆分看下就明白了
例如n=3,那么3>>>31,这个操作就将3的最高位变成了最低位,然后和1与,这样就取到了3的第32位的数据,然后循环以此取出从高到低的数据,拼接成字符串就3的二进制数据了
另外,附上一个辅助看二进制的方法
public static void checkBinary(int n) {
String b = Integer.toBinaryString(n);
b = String.format("%32s", b).replace(" ", "0");
StringBuilder bin = new StringBuilder();
for (int i = 0; i < 4; i++) {
bin.append(b.subSequence(i * 8, i * 8 + 8)).append(" ");
}
L.d(bin.toString().trim());
}
根据需要自行修改
int存储两个数据
最早看到这个是在Android,Message类的源码中看到的,这篇文章我归类于Java所以有关Android源码的部分我就不说了,就大概说一下原理效果.这个可以把一个int型的指定位数来村存储数据.打个比方我用1-3位来存储一个数据,再用4-6位来存储另一个数据,1-3位可以存储的最大数为7,这个是需要注意的,还有就是负数的情况要注意
下面是例子:
public static void main(String agr[]) {
int a = 0;
checkBinary(a);
checkBinary(a |= 6);//给a的1-3位赋值6
checkBinary(a |= (5 << 3));//给a的4-6位赋值5
checkBinary(a & 7);//取出1-3位
checkBinary(a >> 3);//取出4-6位
checkBinary(a&=(~7));//清空1-3位
checkBinary(a&=(~(7<<3)));//清空4-6位
}
输出:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000110
00000000 00000000 00000000 00101110
00000000 00000000 00000000 00000110
00000000 00000000 00000000 00000101
00000000 00000000 00000000 00101000
00000000 00000000 00000000 00000000
上面只是举个例子,我觉的这个是意见比较有意思的事情,实际开发过程中是否使用需要自己斟酌,还有存储的方法,也可以前多少位存储什么后多少位存储什么,或者是用来存储boolean类型的值也都是可以的,可以自由发挥