目录
一、四种进制介绍
二、进制的转换
(一)二进制—>十进制
(二)八进制—>十进制
(三)十六进制—>十进制
(四)十进制—>二进制
(五)十进制—>八进制
(六)十进制—>十六进制
(七)二进制—>八进制
(八)二进制—>十六进制
(九)八进制—>二进制
(十)十六进制—>二进制
三、原码、反码、补码
(一)原码
(二)反码
(三)补码
四、位运算
1.按位与 &
2.按位或 |
3. 异或 ^
4.左移 <<
5. 右移 >>
6.无符号右移 >>>
7. 取反 ~
一、四种进制介绍
对于整数,有四种表示方式:
- 二进制(BIN):0,1,满2进1,以0b或0B开头。
- 十进制(OCT):0-9,满10进1。
- 八进制(DEC):0-7,满8进1,以数字0开头表示。
- 十六进制(HEX):0-9及A(10)、B(11)、C(12)、D(13)、E(14)、F(15),满16进1,以0x或0X开头表示。此处的A-F不区分大小写。
public static void main(String[] args) {
// 二进制
int n1 = 0b1010;
// 十进制
int n2 = 1010;
// 八进制
int n3 = 01010;
// 十六进制
int n4 = 0x10101;
System.out.println("n1=" + n1); // n1=10
System.out.println("n2=" + n2); // n2=1010
System.out.println("n3=" + n3); // n3=520
System.out.println("n4=" + n4); // n4=65793
}
进制的图示:
二、进制的转换
(一)二进制—>十进制
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和。
案例:0b1011转为十进制。
0b1011 =1*2^0 + 1*2^1 + 0*2^2 + 1*2^3 = 1 + 2 + 0 + 8 = 11
(二)八进制—>十进制
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和。
案例:0234转成十进制。
0234=4*8^0 + 3*8^1 + 2*8^2 + 0*8^3 = 4 + 24 + 128 = 156
(三)十六进制—>十进制
规则:从最低位开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
案例:0x23A转为十进制。
23A=10*16^0 + 3*16^1 + 2*16^2 = 10 + 48 + 512 = 570
小练习:将0b110001100、02456、0xA45分别转成十进制
0b110001100 = 0*2^0 + 0*2^1 + 1*2^2 + 1*2^3 + 0*2^4 + 0*2^5 + 0*2^6 + 1*2^7 + 1*2^8
= 4+8+128+256=396
02456=6*8^0 + 5*8^1 + 4*8^2 + 2*8^3 = 6+40+256+1024 = 1326
A45 = 5*16^0 + 4*16^1 + 10*16^2 = 5 + 64 + 2560 = 2629
(四)十进制—>二进制
规则:将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。
案例:34转为二进制。
一个字节有8位,100010是6位,不够8位,前面需要用0补位,所以最终结果:0B00100010
(五)十进制—>八进制
规则:将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制。
案例:131转为八进制
因为八进制是0开头,所以要在203前面补上0,结果为0203
(六)十进制—>十六进制
规则:将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的十六进制。
案例:237转为十六进制
因为十六进制是0x开头的,所以结果为0xED
小练习:
123转成二进制=0b01111011
678转成八进制=01246
8912转成十六进制=0x22D0
(七)二进制—>八进制
规则:从低位开始,将二进制数每三位一组,最高位不足三位,补0。三位以内,按照二进制转十进制的转换规则进行运算。产生的八进制数字按顺序排列
案例:0b11010101转成八进制。
011010101 => 011是3 010是2 101是5 =>八进制为:0325
(八)二进制—>十六进制
规则:从低位次起,每四位看作一组,产生一个十六进制数字,最高位不足四位,补0。四位以内,按照二进制转十进制的转换规则进行运算。产生的十六进制数字按顺序排列。
案例:0b11010101
11010101 => 1101是13 0101是5 => 十六进制为:0xD5
小练习:
0b11100101转成八进制=>0345
0b1110010110转成十六进制=>0x396
(九)八进制—>二进制
规则:将八进制数每1位,转成对应的一个3位的二进制数即可。
案例:0237转成二进制。
02(010)3(011)7(111) = 0b010011111 = 0b10011111
(十)十六进制—>二进制
规则:将十六进制数每1位,转成对应的4位的一个二进制数即可。
案例:0x23B转为二进制
0x2(0010)3(0011)B(1011) =0b001000111011
小练习:
01230转成二进制 01(001)2(010)3(011)0(000) => 0b001010011000
0xAB29转成二进制 A(1010)B(1011)2(0010)9(1001) => 0b1010101100101001
三、原码、反码、补码
二进制在运算中的说明
- 二进制是逢2进位的进位制,0、1是基本运算符。
- 现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用0和1两个数字及其组合来表示任何数。进位规则是“逢2进1”,数字1在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增。
(一)原码
所有的数据在底层都是二进制数据的补码形式存储的
一个数字分为符号位和数值位,1代表负数,0代表正数,符号位在最高位
对于正数来说,原码反码和补码都一样
符号位 | 数值位 | |
---|---|---|
-5 | 1 | 0000101 |
5 | 0 | 0000101 |
(二)反码
负数的反码是在原码的基础上符号位不变,其他位按位取反
符号位 | 数值位 | |
---|---|---|
-5 | 1 | 1111010 |
5 | 0 | 0000101 |
(三)补码
负数的补码是在反码基础上加1
符号位 | 数值位 | |
---|---|---|
-5 | 1 | 1111011 |
5 | 0 | 0000101 |
四、位运算
前提:要把数据转换成二进制数据的补码形式进行运算
位运算是更底层的运算符,效率更高。
1.按位与 &
按位与 &:两个操作数中都是1,结果是1,否则结果是0
任意一个数&一个偶数,结果一定是偶数
任意一个数&1,如果结果是0,就是一个偶数
int a = 10;
if((a & 1) == 0){
System.out.println("偶数"); // 偶数
}
2.按位或 |
按位或 | :两个位中只要有一个是1,那么结果就是1,否则就是0
任意一个数 | 一个奇数,结果一定是奇数
任意一个数与0或,结果还是自身
3. 异或 ^
异或 ^:两个操作数中,相同结果是0,不同结果是1
任何数异或自己都是0,异或0都是自身
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;// b = a ^ b ^ b; b = a
a = a ^ b;// a = a ^ b ^ a a = b
System.out.println(a);
System.out.println(b);
4.左移 <<
左移 << :左边的丢弃,右边补0。左移n位就是乘以2的n次方
3 << 2 相当于3*2的2次方=12
0000 0011
00 001100
5. 右移 >>
右移 >> :右边丢弃,左边补位(正数补0,负数补1) 对于正数来说,右移n位就是除以2的n次方
5 >> 2 相当于5除以2的2次方=1
0000 0101
000000 01
6.无符号右移 >>>
无符号右移 >>> :和右移类似,但是最高位永远是补0
7. 取反 ~
取反 ~ :结论: ~i = -i - 1
~3 0000 0011
1111 1100
- 128 + + 60 + 64
练习:-5 >> 2
一定要注意:要把数据转换成二进制数据的补码形式进行运算!!!
原码:1000 0101
反码:1111 1010
补码:1111 1011
右移2位后的补码 111111 10
反码 1111 1101
原码 1000 0010 -2
结果为:-2