身为计算机从业人员,一直对于二进制不甚了解,为此感到羞愧,今天特地花点时间研究研究二进制。因为暂时没有接触过其他进制的需求,所以此篇博客只会提及二进制和十进制。
1. 十进制转二进制
1.1 正整数
十进制转二进制,需要将值除以2取余,直到最后得到的数是1,如图:
十进制20在经过运算后得到最右边的数:10100(注意箭头的方向是从下往上),所以20转换成二进制后就是10100了。
1.2 负整数
负整数转二进制,需要先取绝对值,再转换成二进制,取反,最后的结果加1即可。
拿-20举例:
- 取绝对值:|-20| = 20
- 十进制转二进制:20(10) = 10100(2)
- 取反:10100 = 01011
- 加1:01011 + 1 = 01100
- -20(10) = 01100
所以-20的二进制就是01100了。
1.3小数
小数转二进制,需要将整数部分和小数部分分开来转换,小数部分乘以2取整数部分,且从上往下取,如图:
十进制12.25转换成二进制后得到的数是:1100.01
2.二进制转十进制
二进制转十进制就相对容易点了,记住下面这个公式就行。
如图可知:
二进制1001转换成十进制就是9
二进制10.01转换成十进制就是2.25
3.二进制移位
计算机中的一个整型占4个字节(byte),而一个byte占8位,所以一个整型应该占32位。还是拿20举例:20(10) = 00000000 00000000 00000000 00010100(2)
3.1有符号左移
有符号左移的符号是:<<
二进制左移就是将二进制的位置向左移动,右边的空位补0。
如:a = 20 << 2的意思就是将20的二进制向左移动2位。我们来计算一下:
- 十进制转二进制:20(10) = 00000000 00000000 00000000 00010100(2)
- 二进制左移:10100 << 2 = 00000000 00000000 00000000 0001010000
- 二进制转十进制:00000000 00000000 00000000 000101000(2) = 80(10)
所以a = 20 << 2 = 80
3.2有符号右移
有符号右移的符号是:>>
二进制右移就是将二进制的位置右移,右移之后的空位用符号位填充,正数补0,负数补1。
如:a = 20 >> 2,我们来计算下:
- 十进制转二进制:20(10) = 00000000 00000000 00000000 00010100(2)
- 二进制右移:00000000 00000000 00000000 00010100 >> 2 = 00000000 00000000 00000000 00000101
- 二进制转十进制:00000000 00000000 00000000 00000101(2) = 5
所以a = 20 >> 2 = 5
我们再来举个负整数移位的例子:a = -20 >> 2,计算如下:
- 十进制转二进制:-20(10) = 11111111 11111111 11111111 11101100(2)
- 二进制右移:11111111 11111111 11111111 11101100 >> 2 = 11111111 11111111 11111011
- 二进制转十进制:11111111 11111111 11111011(2) = -5(10)
3.3无符号右移
无符号右移的符号是:>>>
二进制移位后,空位补0(正负数都是补0)
如:a = 20 >>> 2,我们来计算下:
- 十进制转二进制:20(10) = 00000000 00000000 00000000 00010100(2)
- 二进制右移: 00000000 00000000 00000000 00010100 >>> 2 = 00000000 00000000 00000000 00000101
- 二进制转十进制:00000000 00000000 00000000 00000101(2) = 5(10)
所以a = 20 >>> 2 = 5.
我们再来个负数举例:a = -20 >>> 2:
- 十进制转二进制:-20(10) = 11111111 11111111 11111111 11101100(2)
- 二进制右移:11111111 11111111 11111111 11101100 >>> 2 = 0011111111 11111111 11111111 111011
- 二进制转十进制:0011111111 11111111 11111111 111011(10) = 1073741819(10)
所以a = -20 >>> 2 = 1073741819.
最后的结果可谓是天差地别。
4.& | ^ ~
4.1按位与运算符:&
对两个整型操作数中对应位执行布尔代数,两个位都为1时输出1,否则0。
如: a = 20 & 45,计算如下:
- 20(10) = 00000000 00000000 00000000 00010100(2)
- 45(10) = 00000000 00000000 00000000 00101101(2)
- 20 & 45 = 00000000 00000000 00000000 00000100(2)
- 20 & 45 = 4(10)
4.2按位或运算符:|
对两个整型操作数中对应位执行布尔代数,两个位都为0时输出0,否则1。
如:a = 20 | 45,计算如下:
- 20(10) = 00000000 00000000 00000000 00010100(2)
- 45(10) = 00000000 00000000 00000000 00101101(2)
- 20 | 45 = 00000000 00000000 00000000 00111101(2)
- 20 | 45 = 61(10)
4.3按位异或运算符:^
参与运算的两个值,如果两个相应位相同,则结果为0,否则为1。
0异或任何数=任何数,1异或任何数 = 任何数取反 。
如:a = 20 ^ 45,计算如下:
- 20(10) = 00000000 00000000 00000000 00010100(2)
- 45(10) = 00000000 00000000 00000000 00101101(2)
- 20 ^ 45 = 00000000 00000000 00000000 00111001(2)
- 20 ^ 45 = 57(10)
4.4按位非运算符:~
操作数的第n位为1,那么结果的第n位为0,反之。
如:a = ~20,计算如下:
- 20(10) = 00000000 00000000 00000000 00010100(2)
- ~20(10) = 11111111 11111111 11111111 11101011(2)
- ~20(10) = -21(10)
5.其它位运算符
5.1:<<=有符号左移位赋值,相当于自身有符号左移,如:a = 20, 那么a<<=2后,a就等于80了,怎么来的?自己算去吧!
5.2:>>=有符号右移位赋值,相当于自身有符号右移,如:a = 20, 那么a>>=2后,a就等于5了。
5.3:>>>=无符号右移赋值,相当于自身无符号右移,如:a = -20, 那么a>>>=2后,a就等于1073741819
在这个网址上(http://www.52ij.com/jishu/102.html)看见了这段话,摘过来给大家看看:
由于数据类型所占字节是有限的,而位移的大小却可以任意大小,所以可能存在位移后超过了该数据类型的表示范围,于是有了这样的规定:
如果为int数据类型,且位移位数大于32位,则首先把位移位数对32取模,不然位移超过总位数没意义的。所以4>>32与4>>0是等价的。如果为long类型,且位移位数大于64位,则首先把位移位数对64取模,若没超过64位则不用对位数取模。
如果为byte、char、short,则会首先将他们扩充到32位,然后的规则就按照int类型来处理。
如果文章有欠缺或不对的地方,欢迎大家提出来,我会及时更正的!