除零预防

时间:2012-07-02 19:30:50

标签: c++

什么是1.#INF以及为什么投射到floatdouble会导致0除以崩溃? 还有,如何防止0分裂的任何好主意? (像任何宏或模板一样)?

int nQuota = 0;

int nZero = 3 / nQuota; //crash
cout << nZero << endl;

float fZero = 2 / nQuota; //crash
cout << fZero << endl;

如果我改用:

int nZero = 3 / (float)nQuota;
cout << nZero << endl;
//Output = -2147483648

float fZero = 2 / (float)nQuota;
cout << fZero << endl;
//Output = 1.#INF

3 个答案:

答案 0 :(得分:13)

1.#INF是正无穷大。当你将正浮点值除以零时,你会得到它(如果你将浮点数零除以零,那么结果将是&#34;而不是数字&#34;)。

另一方面,如果将整数除以零,程序将崩溃。

float fZero = 2 / nQuota;崩溃的原因是因为/运算符的两个操作数都是整数,所以除法是对整数执行的。然后将结果存储在浮点数中并不重要; C ++没有目标类型的概念。

为什么正整数转换为整数是最小的整数,我不知道。

答案 1 :(得分:3)

  

使用(float)或(double)可以防止0崩溃?

不一定。在浮点时,标准是惊人的备用。现在大多数系统都使用IEEE浮点标准,并且表示除以零的默认操作是返回±无穷大而不是崩溃。您可以通过启用适当的浮点异常来使其崩溃。

注意:浮点异常模型和C ++异常模型的唯一共同点是“异常”一词。在我工作的每台机器上,浮点异常不会引发C ++异常。

  

另外,关于如何防止除以0的任何好主意?

  1. 简单回答:不要这样做。
    这是其中一个“博士,医生,当我这样做时疼!”各种情况。所以不要这样做!

  2. 确保除数不为零 对用户输入的除数进行完整性检查。始终过滤用户输入以获得理智。当数量应该是数百万时,用户输入值为零将导致除溢出之外的各种破坏。对中间值进行健全性检查。

  3. 启用浮点例外 让默认行为允许错误(这些几乎总是错误)经过不加检查是恕我直言,这是标准委员会的一个重大错误。使用默认值,那些无穷大而非数字最终会将所有内容变为Inf或NaN 默认应该是在其轨道中停止浮点错误,并允许选项允许发生1.0 / 0.0和0.0 / 0.0之类的事情。情况并非如此,因此您必须启用这些陷阱。这样做,你可以经常在短时间内找到问题的原因。

  4. 编写自定义除法,自定义乘法,自定义平方根,自定义正弦,...函数 不幸的是,这是许多安全关键软件系统必须采用的途径。这是一种皇室的痛苦。选项#1已经出局,因为它只是一厢情愿的想法。选项#3已淘汰,因为系统无法崩溃。选项#2仍然是一个好主意,但它并不总是有效,因为糟糕的数据总是有一种偷偷摸摸的方式。这是墨菲定律。

  5. 顺便说一下,这个问题比仅仅除零更糟糕。 10 200 / 10 -200 也将溢出。

答案 2 :(得分:2)

您通常会检查以确保您没有除以零。除非nQuota具有合法值但它确实可以防止崩溃,否则下面的代码并不是特别有用

int nQuota = 0;
int nZero = 0;
float fZero = 0;
if (nQuota)
    nZero = 3 / nQuota;
cout << nZero << endl;

if (nQuota)
    fZero = 2 / nQuota;
cout << fZero << endl;