【问题标题】:why 0.0f/0.0f doesn't generate any runtime error?为什么 0.0f/0.0f 不会产生任何运行时错误?
【发布时间】:2015-02-22 18:07:03
【问题描述】:

最近我测试了以下程序,我期待运行时错误,但它显示“nan”作为输出。为什么和如何?我正在使用 g++ 编译器。

#include <iostream>
int main()
{
   float f=0.0f/0.0f;
   std::cout<<f;
   return 0;
}

同样,我也在 Java 和 C# 中尝试了类似类型的程序,它再次显示 "nan" 作为输出。

class Test
{
   public static void main(String args[])
   {
       float f=0.0f/0.0f;
       System.out.println(f);
   }
}

class Test
{
   public static void Main(string[] args)
   {
       float f=0.0f/0.0f;
       Console.Write(f);
   }
}

我想知道浮点运算是如何实现的以及它与整数运算有何不同。在 C++ 的情况下是未定义的行为吗?如果是,为什么? 请帮帮我。

【问题讨论】:

标签: java c# c++ floating-point nan


【解决方案1】:

来自http://en.wikipedia.org/wiki/NaN#Operations_generating_NaN

产生 NaN 的操作

可以返回NaN的操作有3种:

  • 以 NaN 作为至少一个操作数的操作。
  • 不确定的形式
    • 0/0 和 ±∞/±∞ 分法
    • 0×±∞和±∞×0的乘法
    • 加法 ∞ + (−∞)、(−∞) + ∞ 和等效减法

...等等

【讨论】:

  • 这些实际上是数学中的,称为未确定的,可以在寻找函数的极限时找到
  • @user2397162,我链接到的文章讨论了 IEEE 754,该文档是表示浮点数及其运算的技术标准。
  • 和数学同意他们,如果你不知道,请阅读寻找函数的极限
  • 顺便说一下 Math.Pow(1,Double.NegativeInfinity) 和 Math.Pow(1,Double.PositiveInfinity) 应该给出 NaN 但它给出的 1 与数学冲突!
【解决方案2】:

nan 代表非数字。除以整数 0 总是错误的,因为在数学中你不能除以 0。因此,当您除以整数 0 时,许多语言都会抛出异常。

使用浮点数执行此操作不太合理,因为浮点计算并不精确。例如,计算可能导致0.0f,因为0.0f 是最接近答案的浮点值,而不是因为答案的真实值在数学上为0。因此尝试除以浮点值0.0f 可能不是算法不正确的结果。 nan 本质上意味着无法确定您计算的答案,因为它涉及到两个数字的除法,它是如此之小,以至于计算机无法将它们与 0 区分开来。

【讨论】:

  • 请注意,有些语言也会返回 PositiveInfinity(或等价物),因为某些形式的数学认为这是正确的:msdn.microsoft.com/en-us/library/…
  • @Aravol 谢谢。我已将最后一句更改为“两个数字的除...”,因为正如您正确所说的那样,除以 0.0f 可能会产生 nan 以外的值,具体取决于分子的值。
【解决方案3】:

这是因为默认情况下,C++ 运行时库会屏蔽所有浮点异常。因此,计算会导致 NAN 或 INFINITY,而不是异常。如果你想要异常,你可以在 Windows 上使用函数 _controlfp_s 来取消浮点数。例外

以下代码引发异常。用VS2010编译运行,Win32配置。

#include <float.h>

int main()
{
    _controlfp_s(NULL, 0, _MCW_EM); // enable all floating point exceptions

    float n = 0;
    float f= 0.0f/n;  

    return 0;
}

【讨论】:

  • 为什么不看看&lt;fenv.h&gt;呢?
  • 你能给我证明你的主张吗? “C++ 运行时库掩盖了所有浮点异常”,所以我可以投票给你
  • @Matt 我要求提供来源,以便了解更多信息
  • @KickButtowski 你可以从函数_controlfp_s的链接中找到
【解决方案4】:

你必须知道浮点数允许除零,所以这个:

1.0/0.0

等于无穷大并且这个:

1.0/-0.0

等于负无穷大(-0.0 是负零,如数学中的 1/0-)并且:

0.0/0.0

is NAN 表示不是数字,这在数学缩写中完全不确定。 那是浮点数,但整数会抛出运行时错误,你可能会问为什么,这是因为浮点数是如何以二进制形式表示的,你可以在这里阅读:
http://floating-point-gui.de/formats/fp/
在c#中,你可以说Double.PositiveInfinity、Double.NegativeInfinity和Double.NaN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 2014-07-23
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多