Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么要发生整数溢出?_C#_.net_Overflow_Integer Overflow - Fatal编程技术网

C# 为什么要发生整数溢出?

C# 为什么要发生整数溢出?,c#,.net,overflow,integer-overflow,C#,.net,Overflow,Integer Overflow,在这个问题中,主题是如何使VS检查C#中的算术溢出并引发异常: 其中的一条评论说了一些奇怪的事情,并且得到了很多支持,我希望你能在这里帮助我: 还可以使用checked关键字包装语句或语句集,以便显式检查它们是否存在算术溢出。设置项目范围的属性有点风险,因为通常溢出是一个相当合理的期望 我对硬件了解不多,但我知道溢出与寄存器的工作方式有关。我一直认为溢出会导致未定义的行为,应该尽可能防止。(在“正常”项目中,不编写恶意代码) 为什么你会期望溢出发生,如果你有可能,为什么你不总是阻止它?(通过设置

在这个问题中,主题是如何使VS检查C#中的算术溢出并引发异常:

其中的一条评论说了一些奇怪的事情,并且得到了很多支持,我希望你能在这里帮助我:

还可以使用checked关键字包装语句或语句集,以便显式检查它们是否存在算术溢出。设置项目范围的属性有点风险,因为通常溢出是一个相当合理的期望

我对硬件了解不多,但我知道溢出与寄存器的工作方式有关。我一直认为溢出会导致未定义的行为,应该尽可能防止。(在“正常”项目中,不编写恶意代码)

为什么你会期望溢出发生,如果你有可能,为什么你不总是阻止它?(通过设置相应的编译器选项)

如果你有可能的话,你为什么不一直阻止它


默认情况下未启用选中算术的原因是选中算术比未选中算术慢。如果性能不是您的问题,那么启用检查算术可能是有意义的,因为溢出通常是一个错误。

有一个关于程序员在程序设计中利用溢出的经典故事:

我想要溢出的主要时间是计算散列码。在这里,结果的实际数值大小根本不重要——它实际上只是一个位模式,我碰巧用算术运算处理它


我们已经检查了在项目范围内启用的算术-我宁愿抛出一个异常,也不愿返回不正确的数据。我怀疑这是非常罕见的溢出是可取的。。。我承认我通常把默认值留给未检查的算术,只是因为它是默认值。当然,在生成哈希代码时,也存在速度损失…

比如从字符串生成哈希代码。

我可以想象的另一种可能的情况是随机数生成算法-在这种情况下,我们不考虑溢出,因为我们想要的只是一个随机数。

这与寄存器的工作方式无关,只是存储数据的变量内存的限制。(可以使内存中的变量溢出,而不会使任何寄存器溢出。)

但是回答你的问题,考虑最简单的校验和类型。它只是所有被检查数据的总和。如果校验和溢出,那没关系,没有溢出的部分仍然有意义

其他原因可能包括,您只想让程序继续运行,即使一个无关紧要的变量可能已经溢出

我一直认为溢出的原因 未定义的行为,应 尽可能避免

您可能还对缓冲区溢出(溢出)和数字溢出之间的区别感到困惑

缓冲区溢出是指写入的数据超过非托管数组的结尾。它可能导致未定义的行为,例如使用用户输入的数据覆盖堆栈上的返回地址。在托管代码中很难实现缓冲区溢出


然而,数字溢出定义良好。例如,如果您有一个8位寄存器,它只能存储2^8个值(如果无符号,则为0到255)。所以,如果你加100+200,你不会得到300,而是300模256,也就是44。使用有符号类型的故事要复杂一些;位模式以类似的方式递增,但它们被解释为,因此添加两个正数可以得到一个负数。

这可能与历史和任何技术原因有关。依赖于行为的算法(特别是散列算法)经常使用整数溢出来获得良好的效果

此外,大多数CPU设计为允许溢出,但在过程中设置了进位,这使得在比自然字长的时间内实现加法更容易。在这个上下文中实现checked操作意味着如果设置了进位标志,则添加代码以引发异常。这不是一个巨大的负担,但编译器作者可能不想强加给没有选择的人


另一种选择是默认选中,但提供未选中的选项。为什么不是这样,很可能还要追溯到历史。

你可能期望它出现在测量三角洲的东西上。一些网络设备保持计数器的小尺寸,您可以轮询一个值,比如传输的字节数。如果值太大,它就会溢出回零。如果您经常测量它(字节/分钟、字节/小时),它仍然会为您提供一些有用的信息,并且当连接断开时,计数器通常会被清除,因此它们不完全准确并不重要


正如Justin提到的,缓冲区溢出是另一回事。在这里,您可以将数组的末尾写入不应该写入的内存中。在数字溢出中,使用相同数量的内存。在缓冲区溢出中,您使用了未分配的内存。某些语言会自动防止缓冲区溢出。

使用不断递增的计数器进行计算时。一个典型的例子是Environment.TickCount:

int start = Environment.TickCount;
DoSomething();
int end = Environment.TickCount;
int executionTime = end - start;
如果这一点得到验证,该程序很有可能在Windows启动27天后爆炸。当DoSomething运行时,TickCount滴答超过int.MaxValue时。PerformanceCounter是另一个例子


即使存在溢出,这些类型的计算也会产生准确的结果。第二个例子是生成一个有代表性的位模式所做的数学运算,你对一个精确的结果并不感兴趣,只对一个可复制的结果感兴趣。例如校验和、哈希和随机数。

整数溢出是这样的

你有一个8位整数1111111,现在加上1。000