进制
进制
一、进制概念
十进制是指逢十进一。
计算机中二进制表示数字对于人类来说太长了,一般情况下,通常使用8进制或者16进制来简短的描述2进制。
二、进制的转换
找寻规则:
10进制转换成二进制(倒除法):
52采用倒除法计算除以2的余数,反向统计为110100
二进制转换成十进制:
99== 9 * 10 + 9
876 = 8 * 100 + 7 * 10 + 6
12345 = 1 * 10000 + 2 * 1000 + 3 * 100 + 4 * 10 + 5
56987 = 5 * 10的4次方 + 6 * 10的3次方 + 9 * 10的二次方+ 8* 10的一次方 + 7 * 10的零次方
任何进制转换成10进制规则为:110100 = 1 * 2的二次方 + 1 * 2的四次方 + 1 * 2的5次方 = 4 + 16 + 32 = 52
练习:将以下10进制转换成2进制
123 = 1111011
876 = 1101101100
3456 = 110110000000
987 = 1111011011
将以下二进制转换成10进制
10110011 = 179
1100110011 = 819
1111000011 = 963
1 111 000 011 = 01703
11 1100 0011 = 0x3c3
注意:在Java中,书写2进制使用0b开头,8进制用0开头,十六进制用0x开头。
三、二进制的运算
3.1 与运算
计算规则:同为1则为1,否则为0
3 & 5
0000 0011
0000 0101
0000 0001
4 & 5
0000 0100
0000 0101
0000 0100
3.2 或运算
计算规则:只要有一个为1,结果为1
3 | 5
0000 0011
0000 0101
0000 0111
4 | 5
0000 0100
0000 0101
0000 0101
注意:如果在逻辑判断中使用&或者|,在判断结果上与&&或者||是一样的,但是&&或者||有短路的特征。而&或者|一定要计算两边的结果。
if(a > b) && (c > d), 假设a<b,那么则不去计算c>d的结果。直接返回结果为false。(短路)
if(a > b) || (c > d),假设 a>b,那么则不去计算c>d的结果。直接返回true。(短路)
if(a > b) & (c > d),结果与&&结果一致。但是即使a > b不成立,也会去计算c > d结果。
3.3 非运算
在Java中!作为取反运算符,一般用在boolean变量上,表示取反。
对于数字来说,使用~作为取反(非)运算符。表示各位取反,0变1,1变0
~4 = -5
0000 0000 0000 0000 0000 0000 0000 0100
1111 1111 1111 1111 1111 1111 1111 1011
3.4 异或运算
^作为异或运算符。
计算规则,相异为1,相同为0。
3 ^ 5 = 6
6 ^ 5 = 3
6 ^ 3 = 5
0000 0011
0000 0101
0000 0110
0000 0101
0000 0011
–
0000 0110
0000 0011
0000 0101
规则:任何数与另外一个数字异或两次得到该数字本身。
小技巧:可以不用第三个变量实现两个整数的交换。
3.5 位运算(位移)
>>
向右位移。移动n位相当于除以2的n次方。3 >> 1 = 1 相当于 3 / 2 = 1
0000 0011
0000 0001
3 >> 2 相当于 3 / 4 = 0
<<
向左位移。移动n位相当于乘以2的n次方。低位补03 << 1 = 6 相当于3 * 2 = 6
0000 0011
0000 0110
注意:性能比乘除高得多。
>>>
表示符号位跟着一起移动,一般对负数才看到作用。例如:-2 >>> 1变成int的最大值注意:没有
<<<
符号。
四、原码、反码、补码
计算机中采用二进制方式来存储数字。对于存储数字的格式涉及原码反码补码概念。
注意:正数原码反码补码一样。负数则不同。
4.1 原码
直接通过10进制转换成二进制之后的编码。
例如:3 ,原码为0000 0011
注意:负数的表示方式,在最高位使用符号位1来表示,其他位与正数方式一致。
例如:-3,原码表示为:1000 0011
在计算机中,如果直接采用原码方式来存储,那么有一个问题,当3 + (-3),理论来说应该等于0,实际上会出现0000 0011 + 1000 0011 = 1000 0110,所以不能采用原码方式来存储。
4.2 反码
由于不能采用原码来存储,我们相当于3的相反数是-3,是否可以把-3的原码直接取反,来实现与3相加得到0的效果呢?
于是提出概念,将负数的反码设计为:符号位不变,其他各位取反。对于正数来说,反码与原码一致。
3 原码为:0000 0011
-3 原码表示为:1000 0011,使用反码1111 1100
0000 0011 + 1111 1100 = 1111 1111,发现也不能直接使用反码存储。
4.3 补码
需要使用正数+负数为0的效果,需要在负数的反码的结果上加1.
提出补码的概念,即正数原码反码补码一致,负数补码等于反码+1。
3 原码为:0000 0011
-3 原码表示为:1000 0011,使用反码1111 1100,使用补码1111 1101
0000 0011 + 1111 1101 = 1 0000 0000,由于字节数对于类型的限制,最前面的1会截断(去掉),得到0
理解非运算中-5在计算机以补码的形式存在。
byte b = (byte)128;
1000 0000
1111 1111
1 0111 1111
byte的范围-128 - 127
127 = 0111 1111
-127 1111 1111 1000 0000 1000 0001
0 = 0000 0000
-128= 1000 0000
byte b = 1;
b++;
b = b + 1;
byte与short之间运算结果是int,将一个int赋值到byte中,需要强制转换类型,而b++自带类型转换。
五、浮点数十进制转换成二进制
整数部分按照整数的方式转换。小数部分乘以2,减1
3.2
11.0011001100110011001100110011001100110011
这就是导致浮点数不精确的原因。