关于';浮点异常';在C中

关于';浮点异常';在C中,c,floating-point,floating-point-exceptions,C,Floating Point,Floating Point Exceptions,我有以下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; } 但是当我换线的时候 双x=0; 到 int x=0; 输出变为 Floating point ex

我有以下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;
}
但是当我换线的时候 双x=0; 到 int x=0; 输出变为

Floating point exception

有人能解释原因吗?

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


阅读此

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

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


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

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

int x=0;
double y = 0.0 / x;
因为,在对浮点数进行非法操作时(例如,
0/0
∞×0
,或
sqrt(−1) 

实际上有两种NAN,信号和安静。使用 在任何算术运算(包括数字运算)中发送NaN信号 比较)将导致“无效”异常。用安静的声音 只会使结果太难

本标准规定的NAN表示法有一定的局限性 可用于编码错误类型的未指定位;但是 这种编码没有标准。从理论上讲,信号传递是一个问题 可由运行时系统用于扩展浮点数 使用其他特殊值,而不会减慢计算速度 普通值。不过,这种扩展似乎并不常见

此外,维基百科还说:

整数除零的处理方式通常与浮点不同 点,因为结果没有整数表示形式。一些 当试图分割数据时,处理器会生成异常 整数乘以零,尽管其他人将继续并生成 分区的结果不正确。结果取决于如何划分 已实现,可以是零,有时也可以是最大值 可能是整数


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


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

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

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
我们所能说的最好的情况是,将零除以零实际上是“将不能从零中分辨出来的小东西除以不能从零中分辨出来的小东西”。答案是什么?对于0/0的确切情况没有答案,也没有不准确地处理它的好方法。这取决于相对大小,因此处理器基本上耸耸肩,说“我失去了所有的精度——我给你的任何结果都会误导你”,因为它没有返回一个数字

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


(在第二种情况下是整数除法,但不是第一种,因为C的提升规则。0可以被视为整数文字,并且因为两边都是整数,所以除法是整数除法。在第一种情况下,
x
是双精度的事实导致股息提升为双精度。如果替换
0
by
0.0
,它将是一个浮点除法,无论是
x
的类型。

如果将
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

所有这些关于精度、双精度、小数和浮点的问题什么时候会消失?你被零除,这是不允许的。这是显而易见的,因为
y
现在是双精度的。op已经解决了这个问题。@JonH它可能不像你想象的那样明显,特别是因为双精度值是用文字整数设置的常数:)你的第一段极易引起误解。IEEE-754浮点运算中的基本算术运算将其参数视为精确的。零实际上就是零
0.0/0.0
不会生成NaN,因为“它可能不是零”;它产生NaN是因为没有一个唯一的数字x,0=0*x。@Stephen Canon:当然,FP将输入视为精确的,并在存在时返回最接近的可表示实数。但它们并没有无限的精确性。当精确答案无法表示时,计算中可能出现零;这确实推动了零除法的治疗。考虑X / 0为正X的情况:它给出+无穷大。这并不是因为无穷大*0是任意一个x,而是将零视为“非常小”(而无穷大视为“非常大”)。这个行为很有用,也很有意义,但是对于x=0就不再是这样了。对不起,这是错误的