关于一个数的表示,我们常用的是十进制(人一般有十根手指嘛),另外也可以通过二进制、八进制、十六进制等表示数(可以相互转换),而计算机存储数始终采用的是二进制(逻辑电路中利用电的低电平表示 0 ,高电平表示 1 ,这算硬件限制吧)。这里整理下数的表示方法,以及二进制数的运算。
参考文章:
http://www.ruanyifeng.com/blog/2009/08/twos_complement.html(2的补码)注:我更喜欢叫补码
http://www.ruanyifeng.com/blog/2011/03/4-bit_computer.html#comment-213299(四位计算机的原理及其实现)
http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html(浮点数的二进制表示)
(1)十进制
日常生活中,我们使用的数都是用十进制表示的,如 8 、26 等。
十进制数中,每一位能表示 0~9 这个十个数,超过 9 则溢出,进到下一位,所以称为十进制
(2)二进制
计算机的信息都是以二进制数的形式存储的,每个二进制位(bit)有 0 和 1 二种状态,这个概念也就引入了数的二进制表示。
二进制数中,每一位只能表示 0 或 1 这两个数,超过 1 则溢出,进到下一位,所以称为二进制
(3)八进制
由于计算机中用二进制表示数时,如果数很大,则要写很多的 0 和 1,为了减少数量,所以用八进制来简化。
八进制数中,每一位能表示 0~7 这八位数,超过 7 则溢出,进到下一位,所以称为八进制。
计算机存储八进制数时,实际上还是用的二进制,所以需要 3 个二进制位(能组成 8 种状态,可表示 0~7 )来表示一个八进制位。
(4)十六进制
十六进制和八进制类似,不过每位数能表示的值的范围更大。
十六进制数中,每一位能表示 0~15 这十六位数,超过 15 则溢出,进到下一位,所以称为十六进制。
为了用一位就能表示 10 及以上的数,十六进制中用 A B C D E F 分别指代 10 11 12 13 14 15,所以十六进制数的每位能表示如下十六位数:
0 1 2 3 4 5 6 7 8 9 A B C D E F
计算机存储十六进制数时,实际上还是用的二进制,所以需要 4 个二进制位(能组成 16 种状态,可表示 0~F )来表示一个十六进制位。
(5)进制的转换
【十进制转其他进制】:十进制数作为被除数,其他进制的基数作为除数(如二进制的每位能表示的数的数量为 2 ,即基数为 2,八进制的为 8,十六进制的为 16),依次循环取余数(每次循环重新将商作为被除数),最后把余数从最后得到的开始进行排列,就能得到数对应的其他进制的表示。
【其他进制转十进制】:把其他进制数首先写成加权系数展开式(其他进制的每位数,乘以进制的基数的相应次方,几次方呢?取决于当前位的右侧还有几位,那就是几次方),然后按十进制加法规则求和。这种做法称为"按权相加"法。
如八进制 172=1*8^2 + 7*8^1 + 2*8^0= 64+56+2 = 122,得到十进制 122
【二进制转八进制】:由于使用 3 个二进制位表示一个八进制位,所以只需要按 3 个二进制位进行组合,换算成十进制,就可以得到对应的八进制。
如十进制为16,则二进制为 010 000,那么 3 个二进制位进行组合,换成十进制,则得到八进制 20
【八进制转二进制】:八进制的每位按十进制换算成 3 个二进制位,再组合在一起就可以了。
【十六进制的转换】:类似八进制,只是换成了 4 个二进制位
(6)二进制数中的其他概念
原码:一个十进制数转换成的二进制数,就是原码。如十进制的 11,转成二进制为 1011
反码:将原码的每个位取反,就得到了原码的反码。如 1011 的反码为 0100
【深入理解反码】:因为二进制加法中,相同为 0,相异为 1,所以要取反,就每位用 1 去减,就可以得到每位相反的值了。
【反码的计算】:反码=1111 - 原码 => 原码+反码= 1111(当前数量个二进制位能表示的最大的数)
补码:将原码的反码加 1 ,就得到了原码的补码。如 1011 的反码为 0100,补码为 0101
【深入理解补码】:补码和原码互补,而互补是指两者相加刚好溢出,所以二进制中补码是反码加 1 。如十进制中 40 + 60 = 100(刚好溢出,超出40的两位,多出一位);40 和 60 就互补
【补码的计算】:补码 = 反码 + 1 ;原码 + 反码 = 1111 => 原码 + 补码 = 10000 => 补码 = 10000 - 原码
(7)二进制数的减法
二进制的减法是通过二进制的加法实现的,计算机中负数是用正数的补码表示的,这样可以便于使用加法就能计算减法。
【减法】:原码1-原码2=原码1+原码2的补码
【原理】如十进制中:40的补码为60,因为40+60=100,刚好溢出,进入下一位。
60 - 40 = 20
60 - 40 = 60 +60 = 120(如果计算机只保留两位的话,就会过滤掉溢出位,所以得到 20 ,同理二进制利用补码也能实现减法用加法算)
当然实际中,十进制是这样的:
60 - 40 = 60 - 40 + 100 - 100 = 60 + 60 - 100 = 120 - 100 = 20;
二进制的话,原码1-原码2=原码1+原码2的补码(实际上是加上一个刚好溢出的数,再减去它):
1101 - 0100 = 1101 - 0100 + 10000 - 10000 = 1101 + 1100 - 10000 =11001 - 10000 = 1001
只不过,计算机进行二进制运算时,其中减去 10000 相当于二进制位不够,可以自动舍去,所以直接就是加上补码,而不需要再减一下了。
(8)浮点数的二进制表示
浮点数的二进制表示还是有点复杂,具体可参考阮老师的文章:http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html
(9)二进制加法的计算机原理
二进制、数理逻辑、电子学结合形成了使计算机能进行加法,从而能实现减法、乘法、除法等。
我们知道计算机中只有二进制 0 和 1,而每一个二进制位加法中:
0 0 得 0
1 1 得 0
0 1 得 1
1 0 得 1
这样可以知道二进制加法中,两个二进制位相同为 0 ,相异为 1,也就是【异或】。
而逻辑电路中的逻辑门只有三种:
【与门 AND】:1 1 得 1,其他为 0
【或门 OR】: 0 0 得 0,其他为 1
【非门 NOT】: 1 得 0, 0 得 1
所以二进制加法主要就是要利用这三种逻辑门组成【异或】
如果两个相同,则其中一个取反,再两个相与,那么必为 0
如果两个相反,则其中一个取反,再两个相与,则一个为 1 ,一个为 0
为了实现【异或】,所以再将结果相或,就可以实现相同为 0 ,相异为 1 了
参考文章:http://www.ruanyifeng.com/blog/2011/03/4-bit_computer.html#comment-213299