算术运算导致溢出_计算机中的基本算术运算

算术运算导致溢出_计算机中的基本算术运算_第1张图片
  • 无符号数加法运算

我们回忆一下十进制的加法,在小学的时候,我们是什么方式来计算加法的。10以内的加法全靠背,二位以上呢?对,用竖式表示:

算术运算导致溢出_计算机中的基本算术运算_第2张图片

同类,我们也可以类推出二进制的竖式加法:

2c0ac687aa5dbb045817cc3ce43e79e3.png

使用前面我们提到的n位全加器就可以实现计算机中的加法,第一位相加满2进1,第二位相加,再与进位相加满2进1......,一直处理完最高位。

  • 有符号数加法运算
#include 

看上面的例子,我们都知道在生活中-32768-1=-32769。但是,计算机的结果为什么是32767呢?

前面我们讲过有符号的数值,用补码表示(模运算)。分别转换成无符号数进行加法。在这里short int是2个字节(16位),所以mod 2^16。

-32768+2^16=32768

-1+2^16=65535

(32768+65535)-2^16=32768+65535-65536=32767

使用二进制的竖式表示方式就是:

算术运算导致溢出_计算机中的基本算术运算_第3张图片
Chdy:程序中的运算与基本电路​zhuanlan.zhihu.com
算术运算导致溢出_计算机中的基本算术运算_第4张图片

在上面的竖式表达式中,我们可以发现最高位相加进1,被舍去了!我们前面讲过截断(见上方链接),超过了数据类型的大小就会被截断。这个是最高位是16,所以超过16位,就会被舍去。我们添加补码(模运算),就是将正负号转化数据位,进行相加。换句话说,对于电路来说,是没有正负号的概念,都是数据位相加。所以,数据位的溢出就会影响结果。下面,我们简单说说溢出的判断。

  • 溢出的判断

在计算机中判别溢出通常采用双高位判别法。为此,需引进两个符号:Cs和Cp。

Cs:若符号位发生进位,则Cs=1;否则Cs=0。

Cp:若最高数值位发生进位,则Cp=1;否则Cp=0。

当两个正数补码相加时,若数值部分之和大于2^(n-1),则数值部分必然有进位Cp=1;而符号却无进位Cs=0。这时CsCp的状态为“01”,发生正溢出。

当两个负数补码相加时,若数值部分之和大于2^(n-1),则数值部分补码之和必小于2^(n-1),Cp=0;而符号位肯定有进位Cs=1,这时CsCp的状态为“10”,发生负溢出。

当不发生溢出时,Cs和Cp的状态是相同的,即CsCp的状态同为“00”或“11”。

算术运算导致溢出_计算机中的基本算术运算_第5张图片
  • 无符号乘法运算

在生活中(进行十进制运算),一个数乘以10,结果我们一般都会在那个数后面加个0,乘以100,结果后面加两个0....乘以10^n,结果后面加n个0。类比推理,我们可以知道,二进制也可以用移位的方式(末尾添加0),实现乘法运算。如下实例:

2^5 * 2^3=2^8,这个公式很明显是成立的。如果还看不懂的,我们还是用竖式表示:

算术运算导致溢出_计算机中的基本算术运算_第6张图片
相当于2^5,向左移动了3位

对,2的n次方可以表示向左移动n位,但是并不是所有的数,都是2的n次方可以表示的呀!如果是10101,这个 计算机要怎么计算?哈哈哈...同学,不要忘记了我们不是还有乘法分配率吗?2^5*10101=2^5*(2^4+2^2+2^0)=2^5*2^4+2^5*2^2+2^5*2^0。所以,最后乘法可以转化为左移和加法实现。

  • 有符号数乘法

在加法中,有符号的数,最高位的符号位也作为数据为进行相加。在乘法中,当然也可以作为数值位,进行运算。用以上方法,可以推出有符号位数的乘法。此处不再论述。

  • 除法运算

除法用到的是右移,有符号的右移,就比较特殊(因为有符号位的原因)。有符号的右移,高位需要补符号位,也就是我们说的算术右移(还有一个概念,逻辑右移。他们的区别还是见上面同一个链接)

  • 减法运算

整数的减法运算,我们可以转化为加上一个负数,即转化为有符号的加法运算。

总结:本篇整体了解计算机中的基本算术运算。基本上,计算机使用加法 和移位,实现了加减乘除。浮点数的加减乘除,实际上就是我们的科学计数法相关的运算,此处不再论述。插入一个题外话,学习一个新的知识,我们都需要基础知识来支持。否则,在学习新知识的时候,会有一个空白处。知识结构体系,就没法连接起来。所以,我们的基础知识还是扎实,不要似是而非。

你可能感兴趣的:(算术运算导致溢出)