【算法】详解进制
目录结构:
1,为什么计算机代码需要用2进制表示
大家都知道我们熟练的机制是十进制,也就是(0到9),逢10进1。如果要让电脑使用十进制,首先,应该让电脑能够识别出10个数字。通常的考虑是,通过元器件中电压的高低水平来分别标识10个数字。假如最高电压为10V,那么每个数字标识的就是1V,这种情况造成的后果就是每个数字的电压很容易收到外界电压干扰。除了这种问题,还有一个更大的问题,就是如果要在硬件上识别这10中状态,其电路结构将非常复杂。
由于二进制数只有2个数码,电路就很简单了,因为只有两种稳定状态下的元件。二进制主要有以下优点:
*运算规则简单
*适合逻辑运算
*易进行转化
*抗干扰能力强
2,原码、反码、补码的关系
首先需要知道,电脑的编码都是补码,正数的原码、反码和补码都是一样的,负数的补码的是原码按位取反得到反码后再加1。
比如:
1的原码为:00000001
1的反码为:00000001
1的补码为:00000001
-1的原码为:10000001
-1的反码为:11111110
-1的补码为:11111111
2.1为什么需要反码、补码
计算机中没有减法、乘法、除法运行,都是通过加法来实现的。比如通过1+(-1)来实现减法。
不使用反码和补码:
3-2=3+(-2)=0000 0011+1000 0010=1000 0101=-5
显然结果不正确。
使用反码不使用补码:
3-2=3+(-2)=0000 0011+1111 1101=1 0000 0000=0
这里得到结果的二进制有9位,如果我们只是考虑8位,那么结果取后面8个0,转化位十进制也就是0。
使用补码
3-2=3+(-2)=0000 0011+1111 1110=0 0000 0001=1
使用补码就能得到正确的答案
2.2原码、反码、补码之间的关系
计算机中最终计算的都是机器码,对于数字来说也就是下面的补码。正数的原码、反码、补码相同,负数的反码是原码按位取反(符号位不变),负数的补码是反码加1(符号位不变)。原码的计算规则是,首先得到这个数的绝对值的二进制,然后再判断这个数是正数还是负数,如果这个数是正数把最高位赋值为0,如果是负数就把最高位赋值为1。
比如:-1
原码:1000 0001(-1绝对值的二进制为0000 0001,然后由于-1是负数,所以把最高位赋值为1.)
反码:1111 1110
补码:1111 1111
所以计算机中存储-1的最终代码为1111 1111
比如:-128
原码:1000 0000(首先-128的二进制是1000 0000,然后-128是一个负数所以把最高位赋值为1,恰好最高位已经是1,所以-128原码就是1000 0000)
反码:1111 1111
补码:1000 0000
所以在计算机中存储-128的最终代码为1000 0000
还有需要注意的就是,如果我们在赋值的时候直接给变量赋二进制,那么这里是赋值的就是补码,也就是机器码。
3,进制的转化
3.1 十进制和二进制的相互转化
十进制转二进制规则:整数部分除2取余,倒序排列。小数部分乘2取整,正序排列。
例如
某个数字:15.4
整数部分为:0000 1111。
小数部分为:
0.4*2=0.8 取整为0 余下 0.8
0.8*2=1.6 取整为1 余下 0.6
0.6*2=1.2 取整为1 余下 0.2
...........
保留两位小数,则是01
于是15.4的二进制为0000 1111.01,可通过在线二进制转化器进行验证
二进制转十进制的规则:按权展开,以此相加。
例如
某个二进制:0000 1111
转化为十进制:1*2^(0)+1*2^(1)+1*2^(2)+1*2^(3)+0*2^(4)+0*2^(5)+0*2^(6)+0*2^(7)=15
3.2 八进制和二进制的相互转化
八进制转二进制规则:“一位转三位”;
二进制转八进制规则:“三位合一位”;
3.3 十六进制和二进制的相互转化
十六进制转二进制规则:“一位转四位”;
二进制转十六进制规则:“四位合一位”;
4,一个字节能够表示的数据范围
一个字节有8位,最高位为0表示正数,最高为1表示负数。
那么:
一个字节的正数范围“0000 0000 ”-“0111 1111”,转化为十进制就是“0”-“127”。
一个字节的负数范围“1000 0000”-“1111 1111”,转化为十进制就是“-128”-“-1”。
所以能够表示的数据范围“-128”-“127”。
5,整型数据溢出
接下来在java中运行如下代码:
public class TestYc{ public static void main(String [] args){ byte b=(byte)130; System.out.println(b);//-126 } }
会输出如下-126,byte存储数据的范围(-128 到 127),显然130超过了127,所以存在数据溢出。
我来计算一下,
byte存储的最大整数为:127,对应的二进制代码为:0111 1111。
当把128赋值给byte的时候,也就是127+1,对应的二进制代码为:0111 1111 + 0000 0001 = 1000 0000,对应的十进制为:-128。
当把129赋值给byte的时候,也就是128+1,对应的二进制代码为:1000 0000 + 0000 0001=1000 0001,对应的十进制为:-127。
当把130赋值给byte的时候,也就是129+1,对应的二进制代码为:1000 0001 + 0000 0001=1000 0010,对应的十进制为:-126。
所以从计算我们看出,数据溢出几就在最大数的二进制加上几。