回顾计算机世界的二进制计算

冯诺依曼镇楼,233333333~:
众所周知,计算机世界都是采用二进制进行运算,能够表示0和1,之所以这样设计缘于电路内的电压可以表示为低位与高位,即使受到一些干扰,虽然高位的值和低位的值会有偏差,但高的始终高,低的始终低,进而能够精确地表示0和1两个值,所以最终计算机采用二进制运算,也就是“逢二进一”原则。
那二进制的一些计算由于长期未使用,或者是编程中未接触,已经开始淡忘。这里进行展开回顾:
在这里我给出一个用8个bit(8位)表示的二进制数11111010,然后要求大家求出它的十进制数的值是多少,在这里我直接给出,算出等于250,但是,这样算出的默认值是一个正数的数值,或者是一个无符号数得到的值。
我们课程学习中显然都知道可以给二进制数赋予符号位,那么我们知道了最高位是符号位以后,以上的值又应该等于十进制的多少呢?
计算之前先回顾几个概念:
1、在有符号位的前提下,符号位为0表示正数(0有可能被省略),符号位为1为负数。
2、
正数:
正数的原码、反码、补码都相同。
得到公式: 正数下 ==> 原码=反码=补码
3、
负数:
负数的反码是除开符号位外的各位取反;补码为反码末尾+1。
说人话:负数==>符号位不变,其余按位取反,在末尾加1则为补码==>
原码的反码(原码的反码是除开符号位之外其余取反)+ 1 = 补码
得到公式: 负数下: 原码取反(除符号位)+ 1 = 补码
那么可以推出(补码-1)之后再取反 = 原码
4、
补码:
计算机的底层对二进制数的存储和表示形式都是以补码的形式,也就是说计算机底层不存在原码和反码的概念。至于为什么计算机要用补码形式进行运算, 是为了解决原码不能进行加减运算的问题, 那什么是补码呢?
首先通过时钟的例子来理解补码的由来:假设时钟上的时间为上午10点,为了将时间调整到8点,既可以沿逆时针方向拨2个小时,也可以沿顺时针方向拨10个小时。如果逆时针拨动表示减法,顺时针方向拨动表示加法,那么上述两种操作可以分别表示为:10-2=8,10+10=8(mod 12),即-2和10是等价的,10就是(-2)对12的补码,用公式表示为:-2≡+10(mod 12)。这里mod 12表示“模12”,12表示模数。

从时钟的例子可以看出,当负数用补码表示时,可以把减法转换成加法。在计算机系统中,由于机器码的位数是有限的,所以它可以表示的数的个数也是有限的,即系统是有模数的,模数可以认为是最高位进位的权值。当有n个比特时,这个模就是2^n。
开始计算:
有了以上的概念作基础,那么我们来计算最开始的二进制数 11111010
由于我们知道计算机显示的都是补码,那么11111010是补码。
最终想获得它的十进制的值。
先使用上记公式:
(补码-1)之后再取反 = 原码
11111010 - 00000001 = 11111001
然后符号位不变再取反
就得到了原码10000110。
我们知道最高位的1表示负数。 低位的110 = 0 * 2^0 + 1 *2^1 + 1 * 2^2 = 0 + 2 + 4 =6 , 所以最终得到十进数-6
但是上述的前提是我们引入了符号位的概念作为基础来计算的,但是在计算机的世界里面,是不知道符号位是什么的,计算机只认识补码,我们使用电脑的计算器对 11111010计算的结果也是250, 当引入符号位之后的结果就是-6, 那么这个250和-6大家怎么看待呢,其实这两个值都对,无非就是是否引入符号位的概念问题,其实计算机在运算过程中体现出来的作用, 此处我做了一个实验,将 250 和 -6 做相同的值运算, 250 -3 = 247 -6-3=-9 , 最终无论是正数或者无符号数247还是负数的-9,转换成8bit的二进制数的值都是 11110111,所以我们只需要知道计算机的二进制帮我们做精确的计算过程就够了,是否引入符号位的问题,只是人为的需求加入,抑或是高级编程语言对有符号位变量和无符号位变量的声明来达到表示一个精确的正负值的效果。
以上纯属我个人理解,有错误请指出,欢迎一起交流~
Author: yeafel
v1.5.1