关于C#中的算术运算
使用中间变量交换两个int型变量的值:
int a = 29; int b = 10; a = a+b; b = a-b; a = a-b;
相信大家很容易写出来,但考虑到边界值情况时会有一些有趣的事情。
我们知道有一个int.maxvalue和int.minvalue表示int型的最大值和最小值。
当我们直接定义:int a = int.maxvalue + 1的时候,编译器会提示出错:
在申明x变量时程序编译会报错。
但下面申明的变量a,b进行相加时可以肯定的是出现了算术溢出错误,但却依然可以得到正确的结果。
在执行完a = a+b后发现a的值变成了-3
而后面两步计算均能得出正确的结果….
解释:参考msdn操作符说明:
操作符重载和隐式转换:
算术溢出
算术运算符(、、、)的计算结果可能会超出所涉数值类型的可取值范围。 详细信息应参考特定运算符的相关章节,而一般情况下:
- 整数算术溢出或者引发 overflowexception,或者放弃结果的最高有效位。 整数被零除总是引发 @system.dividebyzeroexception。
发生整数溢出时,具体影响视执行上下文而定,上下文可为 。 在 checked 上下文中引发 overflowexception。 在 unchecked 上下文中,放弃结果的最高有效位并继续执行。 因此,c# 让你有机会选择处理或忽略溢出。 默认情况下,算术运算发生在 unchecked 上下文中。
除算术运算以外,整型类型之间的显式转换也会导致溢出(例如,将 显式转换成 ),并受到 checked 或 unchecked 执行的约束。 但是,位运算符和移位运算符永远不会导致溢出。
- 浮点算术溢出或被零除从不引发异常,因为浮点类型基于 ieee 754,因此可以表示无穷大和 nan(非数值)。
- 算术溢出总是引发 overflowexception。 小数被零除总是引发 dividebyzeroexception。
总结:大多数情况下数值计算很少有机会碰到溢出,但具体特殊场景应具体对待。
如:
1, 变量初始化时给定为int.maxvalue,在使用时一定要考虑计算溢出。
2, 在大量的循环或递归中计算时有可能会导致算术溢出。
3, 从io输入设备中取值,尤其是用户输入的值中很有可能是一个溢出的无效输入。
4, 注意.net clr默认情况下算术运行是发生在unchecked上下文。如果发生算术溢出,程序不会出错,可能得到正确或错误的结果。