首页 > 编程语言 > 详细

C语言数值存储溢出探讨

时间:2020-03-06 22:42:14      阅读:67      评论:0      收藏:0      [点我收藏+]

C语言数值存储溢出探讨

真数与码

真数可以等同于我们数学上的整数,包括正整数,0和负整数。

码是什么呢?

码就是为了存储真数而产生的。

计算机的存储空间不是无穷无尽的,如果未来能实现用一个无穷的二进制位来存储一个数,那么码就没有存在的必要了。

码给各个二进制位设定了一套规则,以达到使用这些二进制位来表示真数的目的。常用的有原码,反码,补码。

现在我们计算机中所使用的的大多是补码,下面的内容也根据补码展开。

如果在提及码的时候没有说明是用多少位来存储的,那么就是在耍流氓

补码

最高位表示符号位,剩余的位表示实际的数据。

这里我假设读者已经熟练掌握真数与补码的转化。

如果没熟练的可以看我写的这篇文章更快的进行进制转换

这里再简单补充一下,补码取最高位为符号位,那么在使用打表法进行快速转换时,最高位的表的值取一个负值即可。例如8位的表取这样的一个序列,-128 64 32 16 8 4 2 1

下面着重介绍当给定的位数无法存储过大或过小的真数(溢出)时,其存储区的变化。

假设我们在用一个8位的存储空间来存储一个数。

其正数最大能存储127,负数最小能存储-128

如果我给出一个真数137,需要存储到这个8位的空间中。

如果我给出一个真数-158,需要存储到这个8位的空间中。

显然,这会产生溢出,那么溢出后,这个存储空间内将会是什么样的内容呢?

技术分享图片

为了解决这两个问题(正溢出和负溢出),我们需要熟悉上图的结构。

左边的是其实际的二进制存储空间的内容

中间的一个循环的线性表,不断重复着从127到-128,再到127,再到-128,再到127,再到-128。。。

右边的是我们的真数

未发生溢出时,真数与我们常规的补码转换一致,但是当真数超过所能存储的范围时,就会陷入到这样一个循环中。

知道了这样一个对应关系之后,我们就可以通过取模运算+数数的方式来计算出发生溢出时,存储空间的实际内容。

所以,经过短暂的计算后可得出

真数137其对应的补码是-119即1000 1001

真数-158其对应的补码是98即0110 0010

下面附上代码验证。

int main()
{
    int8_t a = 137;
    int8_t b = -158;

    printf("a: %0x\n", a);
    printf("b: %0x\n", b);


    return 0;
}

执行结果

a: ffffff89
b: 62

0x89: 1000 1001

0x62: 0110 0010

上面所讲到的只是8位的情况,对于32位,64位也遵循同样的规律。

虽然计算机内部使用的是位运算,计算机并不知道真数这样的概念,甚至计算机内部使用的可能是完全的另一套机制,但是上面的这种计算模型总是能够得到正确的结果。如果世上有一种无限接近现实的简单的模型,那么为什么不用呢?

C语言数值存储溢出探讨

原文:https://www.cnblogs.com/virgildevil/p/12431138.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!