1

我有以下 C 程序:

#include <stdio.h>

int main()
{
double x=0;
double y=0/x;
if (y==1)
  printf("y=1\n");
else
  printf("y=%f\n",y);
if (y!=1)
  printf("y!=1\n");
else
  printf("y=%f\n",y);

return 0;
}

我得到的输出是

y=nan
y!=1

但是当我改变线 double x=0; 到int x = 0;输出变成

Floating point exception

谁能解释为什么?

4

7 回答 7

2

您正在0/0使用整数算术进行除法(这是无效的,并产生您看到的异常)。无论 的类型如何y,首先评估的是0/x

x被声明为 adouble时,零也被转换为 a double,并且使用浮点算术执行操作。

x被声明为 anint时,您将一个int0 除以另一个,结果无效。

于 2011-08-01T18:48:47.927 回答
1

因为由于IEEE 754,在对浮点数(例如 、 或 )进行非法运算时会0/0产生∞×0NaN sqrt(−1)

实际上有两种 NaN,signaling 和 quiet。在任何算术运算(包括数值比较)中使用信号 NaN 将导致“无效”异常。使用安静的 NaN 只会导致结果也是 NaN。

标准指定的 NaN 表示有一些未指定的位,可用于对错误类型进行编码;但该编码没有标准。理论上,运行时系统可以使用信号 NaN 来扩展具有其他特殊值的浮点数,而不会减慢使用普通值的计算。不过,这样的扩展似乎并不常见。

此外,维基百科说这个关于整数除以零

整数除以零的处理方式通常与浮点数不同,因为结果没有整数表示。一些处理器在尝试将整数除以零时会生成异常,尽管其他处理器会继续并生成不正确的除法结果。结果取决于除法的实现方式,可以为零,有时也可以是最大可能的整数。

于 2011-08-01T18:52:13.473 回答
0

如果你除以你int可以int除以0。

0/0双打是NaN

int x=0;
double y=0/x; //0/0 as ints **after that** casted to double. You can use
double z=0.0/x; //or
double t=0/(double)x; // to avoid exception and get NaN
于 2011-08-01T19:06:00.537 回答
0

检查整数数据类型的最小值和最大值。您将看到 undefined 或 nan 结果不在其范围内。

并阅读每个计算机科学家都应该了解的浮点知识。

于 2011-08-01T18:48:39.573 回答
0

整数除以 0 是非法的,不予处理。另一方面,浮点值是C使用NaN处理的。以下如何工作。

int x=0;
double y = 0.0 / x;
于 2011-08-01T18:49:36.720 回答
0

IEE754 中有一个特殊的位模式,表示浮点除以零错误NaN的结果。

但是在使用整数算术时没有这样的表示,因此系统必须抛出异常而不是返回NaN.

于 2011-08-01T18:53:30.187 回答
-1

浮点本质上是对实数进行建模以限制精度。只有有限数量的位模式,但有无限(连续!)数量的实数。它当然会尽力而为,将最接近的可表示实数返回到给定的确切输入。太小而无法直接表示的答案用零表示。除以零是实数中的错误。然而,在浮点数中,由于这些非常小的答案可能会产生零,因此将 x/0.0(对于正 x)视为“正无穷大”或“太大而无法表示”会很有用。这对于 x = 0.0 不再有用。

我们可以说的最好的说法是,将零除以零实际上是“将无法与零分开的小东西除以无法与零分开的小东西”。这个问题的答案是什么?嗯,对于 0/0 的确切情况没有答案,也没有不准确的处理方法。这将取决于相对大小,因此处理器基本上会耸耸肩说“我失去了所有的精度——我给你的任何结果都会误导你”,返回 Not a Number。

相反,当整数除以零时,除数实际上只能精确地表示零。没有办法给它一个一致的含义,所以当你的代码要求答案时,它确实在做一些非法的事情。

(第二种情况是整数除法,但不是第一种,因为C的提升规则。0可以看成整数字面量,因为两边都是整数,所以除法是整数除法。第一种情况,事实上 that xis a double 导致被除数提升为双倍。如果替换0by 0.0,它将是浮点除法,无论 的类型如何x。)

于 2011-08-01T19:00:52.930 回答