2012-10-28 109 views
7

我有一个关于下一个代码问题:除以零 - C编程

int main { 
double x = 0; 
double y = 0/x; 

if(y==1) {.....} 
.... 
.... 
return 0; 
} 

当我运行我的电脑上的代码,我没有得到任何运行时错误,我看到y = -nan(0x8000000000000)。为什么它不是运行时错误除以零?

此外,当我现在将第一行更改为int x = 0; 时,会出现运行时错误。有什么不同?

+3

@Jens:不,C99标准的附录F覆盖了这一点,并且您不会针对浮点得到未定义的行为。并非所有的实现都支持附件F,但是你的和我的都支持。 –

回答

9

您没有得到异常或错误的原因是因为对于双精度定义无穷大和NaN(请参阅IEEE floating point),但是当您尝试使用相同的整数时,将出现错误,因为NaN/Infinity不精确没有定义

+2

你不会总是得到整数'0/0'的错误,这取决于实现。 –

+0

@DietrichEpp:具体取决于CPU。 –

+0

@JanHudec:不一定。 –

13

你不能依赖这个“工作”(即一直在做同样的事情,可移植),它在C中对第二种情况是未定义的行为,对于第一种情况也是如此没有定义__STDC_IEC_559__(我相信,这些日子很少见)。

C99,§6.5.5/ 5

/运算的结果是由第二 从所述第一操作数的除法的商; %运算符的结果是余数。 在这两个操作中,如果第二个操作数的值为 为零,则行为未定义。

你要在一个情况下,“不是数”和而不是在其他的事实是,一个在浮点运算,在这里,您的实现(符合IEEE 754师完成通过零语义),0/0给出NaN。

在第二种情况下,您使用整数算术–未定义的行为,没有预测会发生什么。

+0

应该补充的是,观察到的行为是由平台定义的。 Ix86恰好以这种方式实现零除。 –

+3

对于大多数系统,这实际上是错误的:C99,§F.1:“定义'__STDC_IEC_559__'的实现应符合本附录的规范。当指明C语言和IEC 60559之间的绑定时,IEC60559规定除非另有说明,否则行为均为参考。“ §F。3“运算符”+“,” - “,”*“和”/“提供IEC 60559加,减,乘和除操作。” –

+0

@DietrichEpp:现在好点? – Mat

4

这是因为IEEE 754标准定义了正负无穷大的特殊值以及浮点值的“非数字”。

int这样的非浮点类型没有定义这些特殊值,因此由于未处理的错误而导致运行时间被终止。

这不是特定于C语言的,您会在其他语言中看到非常相似的(如果不是相同的)行为,只是因为此功能归结为硬件。