除以零预防

Divide by zero prevention

本文关键字:      更新时间:2023-10-16
什么是

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

1.#INF是正无穷大。当您将正浮点数除以零时,您将得到它(如果将浮点数零本身除以零,则结果将是"不是数字")。

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

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

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

为什么使用(浮点)或(双精度)可以防止崩溃的除以0?

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

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

另外,关于如何防止除以 0 有什么好主意吗?

  1. 简单的答案:不要这样做。
    这是"医生,医生,当我这样做时很痛!"之类的情况之一。所以不要这样做!

  2. 确保除数不为零。
    对作为用户输入的除数进行健全性检查。始终筛选用户输入以确保理智。当用户输入值为零时,当数字应该是数百万时,除了溢出之外,还会导致各种破坏。对中间值进行健全性检查。

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

  4. 编写自定义除法,自定义
  5. 乘法,自定义平方根,自定义正弦,...功能。
    不幸的是,这是许多安全关键软件系统必须采取的路线。这是皇室的痛苦。选项#1已经出来了,因为它只是一厢情愿的想法。选项 #3 已退出,因为不允许系统崩溃。选项 #2 仍然是一个好主意,但它并不总是有效,因为不良数据总是有潜入的方式。这是墨菲定律。

顺便说一句,这个问题比除以零更糟糕。 10 200/10-200 也会溢出。

您通常会检查以确保没有除以零。下面的代码不是特别有用,除非 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;
相关文章:
  • 没有找到相关文章