我只是想知道,谁负责处理计算机中的数学溢出案例?
例如,在以下C ++代码中:
short x = 32768;
std::cout << x;
在我的机器上编译并运行此代码给了我-32767的结果
“短”变量的大小是2个字节..我们知道2个字节可以容纳最大十进制值32767(如果签名)..所以当我在超过其最大值32767后分配32768到x ..它从-32767重新开始计数到32767等等。 究竟发生了什么,所以在这种情况下给出了-32767的值? 即。什么是在后台完成的二进制计算产生的这个值?
那么,谁决定这种情况发生?我的意思是谁负责决定当我的程序中发生数学溢出时......变量的值只是从其最小值开始,或者例如抛出异常,或者程序只是冻结等等?
它是语言标准,编译器,我的操作系统,我的CPU,还是它是谁? 它如何处理溢出情况? (简单的解释或详细解释它的链接将不胜感激:))
顺便说一句,请问。另外,谁决定我的机器上的'short int'大小是多少?它也是语言标准,编译器,操作系统,CPU等等吗?
提前致谢! :)
编辑: 好的,我从这里了解到:Why is unsigned integer overflow defined behavior but signed integer overflow isn't?
这是处理器定义在溢出情况下发生的事情(例如在我的机器中它从-32767重新开始),取决于处理器的“有符号值的表示”,即。是标志量,一个补码还是两个补码......
是吗? 在我的情况下(当给出的结果再次从最小值-32767开始时...你如何假设我的CPU代表有符号的值,例如-32767的值如何出现(再次,二进制计算,导致这个,请问:)?)
答案 0 :(得分:0)
它不以它的最小值本身开始。它只是截断它的值,所以对于一个4位数,你可以计算直到1111
(二进制,= 15十进制)。如果你加1,你得到10000
,但没有空间,所以第一个数字被删除,0000
仍然存在。如果您要计算1111
+ 10
,则会获得1
。
您可以像在纸上一样添加它们:
1111
0010
---- +
10001
但是,处理器不会累加整个数字,而是直到达到(在这种情况下)4位。在那之后,没有更多的空间可以添加了,但是如果还有1个'进位',它会设置溢出寄存器,这样你就可以检查它的最后一次添加是否溢出。
处理器具有添加数字的基本指令,并且它们具有较小和较大值的指令。一个64位处理器可以加起来64位数字(实际上,通常它们不会加起来两个数字,但实际上是为第一个数字添加第二个数字,修改第一个数字,但这对于故事并不重要)。
但除了64位之外,它们通常还可以加上32位,16位和8位数。这部分是因为如果你不需要更多,只能将8位加起来是有效的,但有时也可以向旧版程序向后兼容,以前的处理器版本最多可以加32位而不是64位。
这样的程序使用一条指令来加总32位数字,并且64位处理器上也必须存在相同的指令,如果有溢出则具有相同的行为,否则程序将无法正常运行在较新的处理器上。
除了使用处理器的核心结构添加之外,您还可以添加软件。您可以创建一个inc
函数,将大块位视为单个值。要递增它,您可以让处理器递增前64位。结果存储在块的第一部分中。如果在处理器中设置了溢出标志,则接下来的64位并将其递增。这样,您可以扩展处理器的限制,以便从软件中处理大量数据。
同样适用于处理溢出的方式。处理器只设置标志。您的申请可以决定是否采取行动。如果你想要一个只增加到65535然后换行的计数器,你(你的程序)不需要对标志做任何事情。