溢出

溢出 属于 C#

1 个练习

关于 溢出

这道练习展示了各种数字类型在溢出时的行为,也就是当它们的容量不足以容纳算术运算或类型转换等计算所产生的结果时会发生什么。

  • 无符号整数(byte、ushort、uint、ulong)会回绕到零(该类型的最大值 + 1 会起到模数的作用),除非大致来说它们出现在checked块中,这时会抛出OverflowException的实例。int和long的行为类似,只是它们分别回绕到int.MinValue和long.minValue。
int one = 1;
checked
{
    int expr = int.MaxValue + one;  // overflow exception is thrown
}

// or

int expr2 = checked(int.MaxValue + one);  // overflow exception is thrown
  • 如果一个字面量表达式会导致它被赋值到的变量溢出,那么就会出现编译时错误。
  • checked状态只适用于直接位于该块中的表达式。被调用的函数中的溢出状态不会被捕获。
  • float和double类型会进入 无穷大 状态,可以用float.IsInfinity()等方法检测。
double d = double.MaxValue;
d *= 2d;
Double.IsFinite(d)
// => false
  • 类型为decimal的数字会抛出OverflowException的实例。
  • 还有一个对应的unchecked关键字,用于你想在checked块内撤销unchecked效果的场合,或用于已经启用编译器设置的情形。

没有抛出异常就发生的溢出可能会带来问题,因为一般来说,错误情况报告得越早越好。

int和float的溢出问题可以通过把结果赋值给long、decimal或double类型的变量来缓解。

如果大整数对你的代码来说必不可少,那么使用BigInteger类型也是一种选择。

当然,有些情况下允许整数回绕是合理的,尤其是无符号值。一个经典的例子是哈希码,它把整数的位宽当作一种求模运算。

你通常会发现,代码库里把uint或ulong用作标识符的地方往往没有检查,因为人们觉得这么做得不偿失。如果从领域就能明显看出不会涉及非常大的值,这也同样适用。不过,看看这个,它是一则警示。

通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 溢出