<?xml version="1.0" encoding="GB2312" ?>
<?xml-stylesheet type="text/xsl" href="../../article.xsl" ?>

<article>

<title>问题往往来自不经意间——编程随想之一</title>

<author>晨光（Morning）</author>

<from type="原作"/>
<copyright/>

<paragraph>
请看下面这段c/c++代码：
<code>
long x = 1;
long y = 1;
long z = x + y;
</code>
</paragraph>

<paragraph>
这几行已经不能再简单了的代码，几乎足以让你开始怀疑我的智力了。但是，千万不要轻视，事情往往会出乎你的意料的。即便是这类“1+1”的简单问题。假如把上面这段代码稍做修改：
<code>
long x = 10……0;
long y = 10……0;
long z = x + y;
</code>
</paragraph>

<paragraph>
我想你该开始意识到我的用意了吧，如果还是迷惑不解，那就真的麻烦了:)试着用cout打印一下z的结果，最大的可能是一个负数。这便是overflow，一个不易为你所察觉的问题，事实上，上述最后一行代码在多数情况下是运行良好的。
</paragraph>

<paragraph>
试想，假如这行代码出现于某个庞大的应用系统，而错误的值被作为中间结论传递给了系统的其他部分，甚而最终的结果又是通过GUI的方式展现出来的。寻找错误的根源将是一项何其艰巨的任务，这真是一个噩梦！
</paragraph>

<paragraph>
对于上述问题的一个简单解决办法是：
<code>
double x = 10……0
double y = 10……0
long   z = (long)(x + y);
</code>
</paragraph>

<paragraph>
但是这只是众多潜在错误中的一个，我们无法预见所有可能的错误，bug永远都无法彻底消灭。也许，就在你书写你自认为漂亮的代码时，错误就在不经意间产生了，悄无声息。
</paragraph>

<paragraph>
对于溢出问题，我到十分愿意为你讲述一个真实的故事，以提请你在这方面的重视。这是一个惨痛的教训，欧洲航天局在一次发射阿利安-5号空间运载火箭的时候火箭失事了，10年的心血，40亿美元的研制代价顷刻间付之一炬。事后发现，起因是火箭控制系统重用了前一代产品的代码，其中有一处将一个64位符点数转换成一个16位整数，它表示火箭的水平偏角。由于新一代产品有了改进，数字取值范围扩大了，结果导致了溢出。
</paragraph>

<paragraph>
最后，我能给你的建议是，保持对此类事件的良好警觉，切莫想当然。此外，经验也很重要，这包括coding和testing。
</paragraph>

</article>