【问题标题】:A few things about division by zero in C [duplicate]C中关于除以零的一些事情[重复]
【发布时间】:2012-09-19 00:06:29
【问题描述】:

可能重复:
Value returning 1.#INF000

我一直认为除以 0 会导致编译后的程序崩溃

但是我今天发现(使用 VC++ 2010 Express)除以 0 得到一个叫做 1.#INF000 的东西,它应该是正无穷大

当它被传递给一个函数时,它被传递为 -1.#IND000

这是怎么回事?

在 google 上搜索 1.#INF000 和 -1.#IND000 也没有提供任何明确的解释

它只是 VC++ 特有的东西吗?

【问题讨论】:

  • 1.#IND000NaN AFAIK 的表示。
  • 我认为结果是 1.#INF000,一个浮点值,这意味着除法是浮点数。否则它肯定是一个未定义的整数值?
  • 1,#INF0001.#IND000不是任何事物的法律代表。该标准要求InfInfinity 表示无穷大,Nan 表示非数字(当然,假设实现支持这些值)。这是 VC++ 中的一个严重错误,并且会导致无穷无尽的问题(尤其是因为没有其他程序会将它们读回为无穷大或不是数字)。

标签: c++ c visual-c++


【解决方案1】:

浮点除以零与整数除以零的行为不同。

The IEEE floating point standard 区分 +inf 和 -inf,而整数不能存储无穷大。整数除以零会导致未定义的行为。浮点除以零由浮点标准定义,结果为 +inf 或 -inf。

编辑:

正如 Luchian 所指出的,C++ 实现不需要遵循 IEEE 浮点标准。如果您使用的实现不遵循 IEEE 浮点标准,则浮点除以零的结果是未定义的。

【讨论】:

  • C++ 由 C++ 标准描述。
  • 具有讽刺意味的是,在默认设置下,Linux 中的进程会获得一个 SIGFPE(“浮点异常”),用于将整数除以零,但不会将浮点数除以零......
  • @LuchianGrigore 这个答案有什么问题?
  • @ouah 结果未定义。行为未定义。
  • @LuchianGrigore:如果std::numeric_limits<double>::is_iec559 为真,那么double 行为必须遵循IEEE 754 规则。所有用于检查的机器,例如NaN(在 C++11 中),如果不是这样,将毫无意义。所以标准中有一个关于“未定义”行为的措辞的缺陷。因为标准中的 UB 意味着对实现没有要求,而后来标准确实(有条件地)施加了这样的要求。
【解决方案2】:

编辑:问题是关于 C++ 的,C++ 中的结果是未定义的,正如标准明确规定,而不是 IEEE 或任何其他实际上不规范 C++ 的实体语言。标准可以。 C++ 实现可能遵循 IEEE 规则,但在这种情况下,行为显然是未定义的。

我一直认为除以 0 会导致编译后的程序崩溃

不,它会导致未定义的行为。任何事情都可能发生,不保证会崩溃。

根据 C++ 标准:

5.6 乘法运算符

4) 二进制 / 运算符产生商,二进制 % 运算符从第一个除法中产生余数 由第二个表达。 如果 / 或 % 的第二个操作数为零,则行为未定义;否则 (a/b)*b + a%b 等于 a。如果两个操作数都是非负数,则余数是非负数;如果不是,余数的符号是 实现定义79)。 (强调我的)

【讨论】:

  • 未定义行为的好处在于编译器可以做任何它想做的事情。即使是与未定义行为完全无关的事情,我也最好始终避免。
  • 只有整数除以零会导致未定义的行为。根据结果​​,这一定是浮点除法。
  • @KlasLindbäck 查看编辑。问题是关于 C++ 的。
  • 您好,感谢您的回复。很抱歉,我的问题并不清楚;我正在使用 VC++ 但代码是 C 代码,但是源文件具有扩展名 cpp 所以我认为它可能正在调用 c++ 编译器
  • @LuchianGrigore,Klas 的回答对吗?
【解决方案3】:

引用 ISO C++ 标准第 5.6 节 ([expr.mul]) 的 latest draft

如果 / 或 % 的第二个操作数为零,则行为未定义。

这适用于整数和浮点除法。

一个特定的 C++ 实现可能符合IEEE floating-point standard,它对除以零有更具体的要求,在这种情况下,行为可能会为该实现很好地定义。这可能就是为什么浮点除以零会在您的实现中产生 Infinity。但 C++ 标准不需要 IEEE 浮点行为。

【讨论】:

  • C 的浮点除以零是否也未定义?
  • @Pacerier:是的。 N1570 6.5.5p5:“在这两个操作中,如果第二个操作数的值为零,则行为未定义。” (参考/%
【解决方案4】:

您可以在 C 中使用以下代码片段。 它抛出异常。虽然它适用于 linux donno 关于 windows

#include <fenv.h>

#include <TRandom.h>
static void __attribute__ ((constructor)) trapfpe(void)
{
    /* Enable some exceptions. At startup all exceptions are masked. */
    feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多