2012-07-02 73 views
8

什么是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 
+2

哇有趣。期待一个答案。 –

+0

这可能是对你有意思:http://blog.regehr.org/archives/721 – cppanda

回答

12

1.#INF是正无穷大。当你将正浮点数除以零(如果你将浮点数零除以零,那么结果将是“不是数字”)。

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

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

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

+0

怎么样-2147483648? –

+1

-2147483648是1.#转换为一个整数。 –

+3

C规范似乎没有指定将'NaN'或无限浮点值转换为整数的结果。 “如果FL浮动值是在无限或NaN或者如果FL浮动值的整数部分超过 整数类型的范围,那么‘‘无效’’浮点数异常上升,所得到的值是unspeci网络编” – mkb

1

您通常会检查以确保您没有被零除。下面的代码是不是特别有用,除非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; 
+0

有点简单,但它像一个魅力。 –

3

Wwhy使用(浮点)或(双)防止被0除崩溃的?

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

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

另外,如何防止除以0的任何伟大的想法?

  1. 答案很简单:不要这样做。
    这是其中的一个“医生,当我这样做时医生会伤害!”种情况。所以不要这样做!

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

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

  4. 编写自定义鸿沟,自定义乘,自定义平方根,自定义正弦,...功能。
    这不幸的是许多安全关键软件系统必须采用的路线。这是一种皇家的痛苦。选项#1出来了,因为这只是一厢情愿的想法。由于系统不能被允许崩溃,所以选项#3已关闭。选项#2仍然是一个好主意,但它并不总是有效,因为糟糕的数据总是有偷偷摸摸的方式。这是墨菲定律。

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