为什么使用二进制计算的时候会出现溢出现象?
什么是溢出?
溢出,是指数据的大小,超出了编码所能表示的范围。
发生溢出时,该组编码,就不能正确的表示数据。
不仅是补码计算,任何形式的计算,都可能产生溢出。
比如:1999 年、2000 年 ...,这是用 4 位十进制表示。
当到了 9999 年,再过一年,你如果还用 4 位表示,就会溢出了。
如果不限制编码的位数,那么,就不存在溢出的问题了。
-----------------------------
无符号数的溢出
计算机所能运算的位数是固定的,如:八位机、16、32、64 位机。
当字长为八位时,其计数范围是:0000 0000~1111 1111。
它们可以表示【自然数】,写成十进制就是:0~255。
在小学学过的【自然数】,在计算机专业,被偷改为“无符号数”。
---------------
如果在其最大值(255)再加上一,就会超出表示范围,发生溢出。
此时,八个位就都为 0,进位将为 1。
进位为 1,就是无符号数溢出的标志。
进位 1,代表十进制的 256。
256 是八位二进制数的计数周期,又被计算机专业改称为“模”。
----------------------缓派厅-------
带符号数的溢出
八位二进制也能表示【整数】,包括了【正整数、零和负整数】。
在小学学过的【整数】,在计算机专业,被偷改为“带符号数”。
此时,0 ~ 127,就直接代表【零和正整数】;
128~255,是以补码代表【负整数】,即代表-128~-1。
---------------
在正羡段数最大值(+127)上再加+1,就会超出表示范围,发生溢出。
此时得到的是 128,这是负扰隐数(-128)的补码。
注意,虽然此时的进位为 0,但是仍然是溢出了。
结果的符号错误,才是溢出的特征。
---------------
在负数最小值(-128)再加-1,也会超出范围,发生溢出。
计算如下:
1000 0000
+ 1111 1111
---------
(1) 0111 1111
此时,竟然得到了正数(+127)!
注意,此时的进位为 1,并无意义。
结果的符号错误,才是溢出的特征。
---------------
“带符号数”溢出的特征是:运算结果的符号,与正常结果相反。
“带符号数”的溢出,与进位是 1 是 0,并无关系。
---------------
判断是否溢出的方法
因为“带符号数”运算发生溢出,必定是结果超出范围。
所以,只有如下四种运算,才有可能出现溢出:
正数+正数、负数+负数、正数-负数、负数-正数。
其它运算如:正-正、...,就不必考虑溢出了。
由人工计算:就可根据数据的符号来判断,如:
正+正,出现负的结果;
负+负,出现正的结果;
... ...
发生上述四种之一,就是溢出。
另外,也可考查进位与次高位的进位,两者不同,就是溢出。
用 CPU 计算:CPU 能够自动判断,如果发生溢出则会置位 OF。
-----------------------------
使用二进制计算的时候会出现溢出现象,是因为计算宏扒仔机都有它的上限和下限,太大的数值和太小的数值都是无法显示出来的。
计算机中用补码来表示和存储数值,而在进行数值的算术此清运算时由于机器字长的限制往往会出现补码溢出,导致计算结果错误。
针对这个问题,提出蔽汪了一种根据溢出结果得到正确结果的计算方法:
两个正数相加溢出时,将错误解加上2~(n+1)即为正确解;
两个负数相加溢出时,将错误解减去2~(n+1)即为正确解。
不仅是二进制,任何进制的计算,都可能产运早键生溢出。
比如:1999 年、2000 年 ...,这是用四位十进制表示。
当到了 9999 年,再过一年,你如果还用四位表示,这就溢出了。
字长为 8 位二进制,补码的范围是-128 至+睁历127。旁巧
那么,+125 + 4 = +129,这就溢出了。