记得以前玩游戏的时候,积攒下来的金币越来越多。看着那个数字长呀、长呀,突然有一天,我的钱莫名其妙的变成了负数!真是悲剧。
走上了软件开发这条路之后,知道了,这叫做“溢出”。做了这么多年的开发,说实话,还真的没有在程序中特别注意过溢出的检查。
所以,今天把它写出来,就算是提醒一下自己和跟我一样没有注意过这个问题的朋友们吧。
1、溢出现象
做开发的人,应该都知道什么是溢出,这里就不说关于多溢出的基础知识了,简单看一下下图,变量int3变成了负数。
2、溢出检查
怎么样才能避免这种错误的发生呢?在c#中可以用“checked”关键字对可能发生溢出的代码段进行溢出检查。如果“checked”包含的代码段中发生溢出时,将会报异常。
看到下面这张图了吧,同样的代码,加了一个“checked”,就运行不过去了,自己加上一个try catch处理一下吧。
3、统一设置溢出检查
坦白的说,我是一个懒人,我才不想一个地方、一个地方的去找、去加“checked”呢,万一少遗漏了一个地方,那麻烦不就大了吗?
有没有统一设置的地方,设置一次,所有代码都进行溢出检查呢?呵呵,有的。
在项目属性里,依次进入,生成-->高级,再勾选“检查运算符上溢/下溢”,就好了。
看到了吧,没有加“checked”,照样报了异常
3、溢出检查的性能损失
下面的列表显示了,一段相同的代码,在检查和不检查溢出的运行耗时。可以看出,两者性能相差7.81%。
好了,不多说了,是节约这7.81%的性能,还是保证运算的准确行,根据实际情况,具体分析吧。
运行耗时 | ||
检查溢出 | 1 | "00:00:03.4962992" |
2 | "00:00:03.5251535" | |
3 | "00:00:03.5164421" | |
不检查溢出 | 1 | "00:00:03.2255009" |
2 | "00:00:03.2309986" | |
3 | "00:00:03.2580578" |
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestApp { class Program { static void Main(string[] args) { System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); var count = 0; for (int i = 0; i < 1000000000; i++) { count++; } timer.Stop(); var str = timer.Elapsed.ToString(); } } }