除以零 - c 编程
Posted
技术标签:
【中文标题】除以零 - c 编程【英文标题】:divide by zero - c programming 【发布时间】:2012-10-18 03:06:55 【问题描述】:我有一个关于下一个代码的问题:
int main
double x = 0;
double y = 0/x;
if(y==1) .....
....
....
return 0;
当我在我的计算机上运行代码时,我没有收到任何运行时错误,并且我看到了 y = -nan(0x8000000000000)
。为什么除以零不是运行时错误?
另外,当我将第一行更改为int x = 0;
现在出现运行时错误。有什么区别?
【问题讨论】:
@Jens:不,C99 标准的附件 F 覆盖了这一点,您不会得到浮点的未定义行为。并非所有实现都支持附件 F,但你和我的都支持。 【参考方案1】:您根本不能依赖这种“工作”(即一直在做同样的事情,可移植),对于第二种情况,它在 C 中是未定义的行为,如果您的实现没有定义,对于第一种情况也是如此__STDC_IEC_559__
(我相信,现在很少见了)。
C99,§6.5.5/5
/ 运算符的结果是第一个操作数除以 第二; % 运算符的结果是余数。 在这两种操作中,如果 第二个操作数为零,行为未定义。
您在一种情况下得到“不是数字”而不是在另一种情况下得到的事实是,一个是在浮点算术中完成的,其中,在您的实现中(符合 IEEE 754 除以零语义) , 0/0
给出一个 NaN。
在第二种情况下,您使用的是整数运算 - 未定义的行为,无法预测会发生什么。
【讨论】:
需要补充一点,观察到的行为是由平台定义的。 Ix86 恰好以这种方式实现除零。 这对大多数系统来说实际上是错误的:C99,§F.1:“定义__STDC_IEC_559__
的实现应符合本附件中的规范。其中 C 语言和 IEC 60559 之间的绑定除非另有说明,否则 IEC60559 规定的行为以引用方式采用。” §F.3 “+
、-
、*
和 /
运算符提供 IEC 60559 加、减、乘和除运算。”【参考方案2】:
您没有收到异常或错误的原因是因为定义了双精度、无穷大和 NaN(请参阅 IEEE floating point)但是当您尝试对整数进行相同操作时,您会收到错误,因为 NaN/Infinity没有定义
【讨论】:
整数0/0
不会总是出错,这取决于实现。
但我只更改 x 值而不更改 y 值。所以就像之前说的一样。没有?
@JanHudec 不,编译器还可以对 n/0
是 UB 这一事实进行优化。编译器可能会删除这个if
-block n=a/b; if(!b) /*This code will be removed*/
。【参考方案3】:
这是因为IEEE 754 标准定义了正无穷和负无穷的特殊值以及浮点值的“非数字”。
像int
这样的非浮点类型没有定义这些特殊值,因此运行时由于未处理的错误而终止。
这不是 C 特定的,您会在其他语言中看到非常相似(如果不相同)的行为,仅仅是因为此功能取决于硬件。
【讨论】:
以上是关于除以零 - c 编程的主要内容,如果未能解决你的问题,请参考以下文章
用c语言编写程序,用Switch语句编程实现,输入一个正整数,输出该整数除以5的余?
Linux C/C++ 零基础学习编程教程,Linux 系统编程教程