为什么要发生整数溢出?

mag*_*tic 25 .net c# overflow integer-overflow

在这个问题中,主题是如何使VS检查C#中的算术溢出并抛出异常:C#溢出不起作用?如何启用溢出检查?

其中一条评论说得有些奇怪,而且投票很多,我希望你能在这里帮助我:

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

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

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

Jon*_*eet 35

想要溢出的主要时间是计算哈希码.在那里,结果的实际数值大小根本不重要 - 它实际上只是我碰巧用算术运算操作的一个模式.

我们检查了Noda Time项目范围内的算术运算- 我宁愿抛出异常而不是返回错误的数据.我怀疑溢出是非常罕见的......我承认我通常会将默认值保留为未经检查的算术,因为它是默认值.当然还有速度惩罚......

  • 你的精确度和速度真的很烦人.恭喜! (10认同)

Rei*_*ica 10

我一直认为溢出导致未定义的行为,应尽可能防止溢出.

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

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

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


Han*_*ant 9

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

int start = Environment.TickCount;
DoSomething();
int end = Environment.TickCount;
int executionTime = end - start;
Run Code Online (Sandbox Code Playgroud)

如果检查过,程序有可能在Windows启动27天后轰炸.当DoSomething运行时,TickCount超过int.MaxValue.PerformanceCounter是另一个例子.

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

  • @Jon - 绝对没有,计算是正确的. (5认同)
  • @darron - 这与*1*毫秒的时间测量相关.'溢出不止一次'的角度是27天.或54,取决于. (2认同)

Dou*_* T. 5

溢出的整数是测量角度的优雅工具.你有0 == 0度,0xFFFFFFFF == 359.999 ....度.它非常方便,因为作为32位整数,你可以加/减角度(350度加20度最终溢出环绕回到10度).您还可以决定将32位整数视为有符号(-180到180度)和无符号(0到360).0xFFFFFFF等于-179.999 ...,相当于359.999 ......,这是公平的.很优雅.