数值系统(各进制转换原理和位运算基础)
本
篇是我第一篇原创基础类文章我将讲到数值系统中的进制和各进制间的相互转换,如二进制转换为八进制十六进制,八进制十六进制转换为二进制,二进制八进制十
六进制转换为十进制,十进制转换为二进制八进制十六进制等。另外我还会讲到计算机中负值的二进制表达法:补码表达法。并简单的引进下位运算。
为了简洁,方便大家直接拿过来用,我就简单的介绍下,然后就直接写出各进制间的转换方法,大家直接参考转换公式就可以了,当然进制间的转换并非一种,当然我只举出最常用的。闲话少说——GO!
首先有必要讲一下各进制的基数 ,见下表:
属性 二进制 八进制 十进制 十六进制 基数 2 8 10 16 最小位数 0 0 0 0 最大位数 1 7 9 F
上述的各种数值系统都是采用的数位记数法 (positional notation),也就是说每个位数上都有一个不同的位值
。
如:1234(十进制),我们说1在千位上,2在百位上,3在十位上,4在个位上
每个位值 都是基数 的乘幂 ,其乘幂从右至左依次递增,从0开始,每次递增1。如下表:
数位 1 2 3 4 位名 千位 百位 十位 个位 位值 1000 100 10 1 位值的乘幂 (十进制的基数 为10)
10的3次幂 10的2次幂 10的1次幂 10的0次幂 依次类推万位的位值 就是10的4次幂,十万位的位值
就是10的5次幂,千万位的位值 就是10的6次幂..... 对于二进制,八进制,十六进制也是以此类推,例如二进制10110: 数位 1
0 1 1 0 位名 十六位 八位 四位 二位 一位 位值 10 8 6 4 2 位值的乘幂 (二进制的基数 为2) 2的4次幂
2的3次幂 2的2次幂 2的1次幂 2的0次幂
八进制2046:
数位 2 0 4 6 位名 五百一十二位 六十四位 八位 一位 位值 512 64 8 2 位值的乘幂 (二进制的基数 为2)
8的3次幂 8的2次幂 8的1次幂 8的0次幂
十六进制A6E2
......(以此类推)
知道以上的知识后,我们便开始进制转换
首先从各进制转换为十进制 开始
要从各进制转换为十进制非常的简单,只要让每个数位 *相应数位 的位值 ,再把这些结果加起来,得到的便是十进制了
举例:八进制3225转换为十进制
数位 3 2 2 5 位值 512 64 8 2 乘积 3*512 2*64 2*8 5*2 位值的乘幂 (二进制的基数 为2)
1536+128+16+10=1690
那么八进制3225转换为十进制就是1690,二进制,十六进制转换成十进制的方法也以此类推,只不过因基值 的不同乘的位值
不一样罢了。
下面我们开始讲从二进制转换成八进制十六进制,然后再讲从八进制十六进制制转换为二进制。
二进制转换成八进制十六进制
八进制十六进制数值系统和二进制之间有一个规律,就是八进和十六进制的基数 8,16都是二进制的基数 2的乘幂
由此规律我们可以得出一种拆分转换 的方法,我们可以将二进制拆分 成每组 3个(八进制)或4个(十六进制)的组
如下:
比如二进制为:1100011010001,我们将之转换成八进制就是:
(分组 从后往前开始,如果前面不足3位,或4位则用0填满)
001 100 011 010 001 1 4 3 2 1
原理其实我举个例子大家一看就懂的,二进制111转换成十进制为多少?翻翻上面的所说的各进制转换成十进制的方法我们知道为6。
那么二进制1111转换成十进制为多少?对的,是15,也就是十六进制的F,记得上面我发第一张表吗?道理很简单,相信大家都很聪明的发现了一则规律。
是 的,因为八进制和十六进制的基数是二进制的乘幂 ,八进制8是二进制2的3次幂,按二进制转换成十进制的方法:每个数位 *相应数位
的位值
得出的结果111永远不会超过7,1111永远不会超过15的规则那么二进制转换成八进制十六进制和二进制转换成十进制的方法一样行的通,只不过把二进制
分为不同的3位一组,4位一组罢了。
说到这里我们该来说说从八进制十六进制制转换为二进制 了
上面我们知道了如何将二进制转换为八进制十六进制,做法是对二进制进行分组
,然后写出每一组所对应的十进制数,拼起来就是八进制或十六进制了。
这一操作其实逆过来便是从八进制十六进制转换为二进制的方法了。
举例:十六进制A6E2转换成二进制便是:
(不足的前面用0代替)
A 6 E 2 1010 0110 1110 0010
OK,我们的进制转换讲完了,下面我再说下负数的二进制表达法 :补码表达法
我们依然举例来说明,如:
Java代码
int intJyasa =
15;
int intJyasa = 15;
则i在计算机里的二进制表示方法为(假设计算机为32位):
0000 0000 0000 0000 0000 0000 0000 1111
这时我们进行取反操作,得到intJyasa 的反码 (0变成1,1变成0):
1111 1111 1111 1111 1111 1111 1111 0000
为了得到intJyasa 的负值的表达方法(也就是补码 ),只需将intJyasa的反码加1 ,即:
1111 1111 1111 1111 1111 1111 1111 0001
我们继续来探讨其原理,首先我们将intJyasa(15)和其补码 (-15)相加,你会发现结果为0,如下:
(二进制相加为逢二进一 ,六进制,八进制以此类推)
0000 0000 0000 0000 0000 0000 0000 1111 + 1111 1111 1111 1111 1111
1111 1111 0001 = 0000 0000 0000 0000 0000 0000 0000 0000
(注意最左边多出来的我们舍弃掉它)
我们得到了0,如果我们将一个数的反码 加上该数,结果将全得到1,如:
0000 0000 0000 0000 0000 0000 0000 1111 + 1111 1111 1111 1111 1111
1111 1111 0000 = 1111 1111 1111 1111 1111 1111 1111 1111
要得到全0的关键是用反码 加1得到补码
(为什么要得到0?15加-15是不是等于0呢?我们要去到负的必须想办法使它等于0),这就是为什么让intJyasa(15)反码 加1
的道理了,加1导致每位变为0并进1。进位一直左移,直到最左边的二进制位将它丢弃,最终得到结果0(因为计算机表达32位int型变量只能在内存里记录
32位,多出会抛弃掉)
呵呵,巧妙吧。你会发现设计计算机的人是多么的不可思议。
为了推论正确性我们来模拟下计算机演算减法的原理
如:
Java代码
int intX,intY,intZ;
intX = 0; intY = 15;intZ = 6;
intX = intY - intZ;
//实际上就等同于将IntZ的补码加上intY,如下:
intX = intY + ( ~intZ + 1
);
int intX,intY,intZ;intX = 0; intY = 15;intZ = 6;intX = intY -
intZ;//实际上就等同于将IntZ的补码加上intY,如下:intX = intY + ( ~intZ + 1 );
不信你可以上机试试看,转换成机器码为
intY :0000 0000 0000 0000 0000 0000 0000 1111 + intZ反码:1111 1111 1111
1111 1111 1111 1111 1010 =
intZ :0000 0000 0000 0000 0000 0000 0000 1001
一位一位的左移,直到最左边的被遗弃,你会发现结果真的等于9。
相信大家已经看出来原理了,希望我的东西没白写,这是本人第一篇基础类原创文章,居然写了近3个小时,好累啊,都凌晨近4点了。
这里我引入了~(取反)运算符,该运算符属于位运算范畴,下篇文章我就详细的讲位运算(不出意外的话,呵呵)。
最后在给大家一张表,方便大家更快的进行进制转换(其实中途的时候我便想列出来,但为了想让大家自己动手在纸上演算,所以我放到最后):
二进制 十进制 八进制 十六进制 0 0 0 1 1 1 1 2 10 2 2 3 11 3 3 4 100 4 4 5 110 5
5 6 111 6 6 7 1000 7 7 8 1001 8 10 9 1010 9 11 A 1011 10 12 B 1100
11 13 C 1011 12 14 D 1101 13 15 E 1110 14 16 F 1111 15 17 G
全部完结