版权归原作者所有,如有侵权,请联系我们

[科普中国]-算术溢出

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

算术溢出(arithmetic overflow)是指计算机进行算术运算产生的结果超出机器所能表示的范围。溢出有上溢和下溢之分,在定点计算机和浮点计算机中,上溢和下溢的概念是不完全相同的。在定点计算机中,从正方向超过了数的表示范围,称为上溢;从负方向超过了数的表示范围,则称为下溢。在浮点计算机中,浮点数的表示范围主要由阶码来决定。不论数的符号是正还是负,若阶码从正的方向超出了阶码的表示范围,称为上溢;若阶码从负的方向超出阶码的表示范围,或者尾数为“0”时,统称为下溢。一般来说,计算机对于浮点数的下溢,则自动当作“0”来处理,不输出错误信息;而产生的上溢,计算机则产生“溢出中断”,并输出溢出的错误信息,甚至停止程序的运行1。

简介算术溢出(arithmetic overflow)或简称为溢出(overflow)指的是:在计算机领域里所发生的溢出条件是,运行单项数值计算时,当计算产生出来的结果是非常大的,大于寄存器或存储器所能存储或表示的能力限制。在计算机领域里,运行多项或累计的数值计算时,当计算产生出来的总值是非常大的,大于寄存器或存储器所能存储或表示的能力限制。要注意的是,溢出可能会在其他地址被置换。

加法器是中央处理器算术逻辑单元中的核心之一。当长度为n位的两个二进制数经过加减法器运算,得到的长度为n位的结果不是正确值时,我们说发生溢出。

算术下溢算术下溢也称为浮点数下溢,是指计算机浮点数计算的结果小于可以表示的最小数。算术下溢在计算结果很接近零出现,使得计算结果的大小小于浮点数可以表示的最小数字。算术下溢也可以视为是浮点数指数在负值时的溢位。例如,浮点数指数范围为-128至127,一个绝对值小于2−127的浮点数就会造成下溢(假设-128的阶码用于表示负无穷)。界于−fminN and fminN之间的区间称为下溢间距(underflow gap),其中fminN为一般浮点数格式所能表示的最小正数。

在早期的设计中,界于下溢间距之间的数字其值均视为零,因此若出现算术下溢,其结果会被改为零,可能是用硬件或系统软件处理,此处理方式称为“清洗为0”(flush to zero)。

1984年版的IEEE 754导入了次正规数,次正规数和零可以填满下溢间距。假设浮点数指数范围为-128至127,最小可表示正规数为2^−127,次正规数则是类似0.9^−127、0.8^−127……之类的数,计算时会将结果转换为最接近的次正规数,因此可以渐近下溢,不过最接近的次正规数中仍有可能是零。

出现算术下溢时,可能会设定一个状态位元、产生异常、产生中断或是这几项的组合。

IEEE 754中规定只有算术下溢会造成精确度下降时才回报算术下溢,一般是在最后的计算结果不对时才会出现。但若程式要捕捉算术下溢,不论是否有精确度,都会回报算术下溢。IEEE 754处理算术下溢及其他异常的方式相同,都要纪录算术下溢时的浮点运算器状态。

控制溢出有几个控制溢出的方法:

设计:选择正确的数据类型,尤其要注意数据长度与signed/unsigned数据符号。

回避:事先注意指令的运作以及检查运算的数值,或许可以确保计算出来的结果不会超过存储器存储数据的限制。

控制:当它被侦测到,还有在其他的程序完成时被检测出来,那么溢出是可以被预料的。例如:两个比特大的两个数值做加法计算,这种情形最可能发生,步骤如下:先加低比特再加高比特,但是如果它必须完成低比特的运算,就会产生比特加法的运算溢出,那么就有必要做侦测和增加高比特的总和。通常CPU有支持侦测数值加法大于寄存器大小的作法,基本上这个作法是采用状态比特的方式。

增值:假如存储的数值过大就会被分配给其他特定的数值,这时溢出就会发生,然后传回旗标值时就会产生连续运作的现象。检查这个问题最有用的方法,就是在整体的计算结尾做一次性的检查工作,而不是检查每一个运行步骤。这个作法最常用在浮点硬件调用浮点运算器。

忽略:这是最普遍的作法,但是这个作法会得出不正确的结果,以及降低程序的安全性。

检查溢出大多数的计算机都可以区别以上两种溢出条件。当加法或减法的结果发生进位,必须考量到当运算的数值与结果都是unsigned numbers(无号数值,即“正数”)类型时,运算的结果就不适合使用这个数值类型。所以,在运行无号数值(正数)的加法或减法之后检查进位旗标是非常有用的作法。“溢出”在运算结果为无号数值时容易发生,可以从有符号的运算数值预计出这类的情形(例如:两个正整数相加产生的结果为一个负数)。所以,在运行2的补数的加法或减法之后检查溢出旗标是非常有用的作法(换言之,有考虑到有号数值)。

定义A和B都是长度为n位的二进制数

以下是竖式(第一行为进位):

其中的进位

1、输入的数是无符号整数,我们通过观察C判断是否溢出

a) C=1

i)如果是加法操作,结果不正确,结果溢出

ii)如果是减法操作,结果正确,结果未溢出

b) C=0

i)如果是加法操作,结果正确,结果未溢出

ii)如果是减法操作,结果不正确,结果未溢出。在这种情况下,结果是负数。然而,在无符号整数世界里,负数不存在,我们认识这样的操作是非法的。当然,如果认为答案是以有符号整数补码的形式出现,则结果正确。

2、输入的数是有符号整数,我们通过观察V判断是否溢出

a) V=1,结果不正确,结果溢出

b) V=0,结果正确,结果未溢出

本词条内容贡献者为:

李嘉骞 - 博士 - 同济大学