当我编译该程序:
#include <stdio.h>
int main(void)
{
int x, y = 0;
x = 1 / y;
printf("x = %d\n", x);
return 0;
}
它给出了“浮点异常(核心已转储)”
然而,当我编译:
#include <stdio.h>
int main(void)
{
double x, y = 0;
x = 1 / y;
printf("x = %f\n", x);
return 0;
}
它显示“ x = inf”
为什么在使用double时为什么返回x作为无穷大,而在使用int时为什么返回错误?
答案 0 :(得分:7)
C标准明确规定,对于整数或浮点操作数,以零除具有未定义的行为。
C11 6.5.5第5段:
/
运算符的结果是除以 第一个操作数第二个;%
运算符的结果是 余。在两个操作中,如果第二个操作数的值是 零,行为是不确定的。
未定义的行为意味着该标准对发生的事情一无所知。它可能会产生有意义或无意义的结果,可能会崩溃,或者可能会像标准的笑话一样使恶魔从您的鼻子中飞出。 (当然,后者不会发生,但是如果这样做的话,它不会违反C标准。)
与整数类型不同,浮点类型通常具有不代表数字的特殊值。 IEEE浮点标准指定除以零会产生无穷大的结果,这是您的实现正在执行的操作。整数没有“ Infinity”值。 (请注意,C实现可能符合或可能不符合IEEE浮点标准。)
This question讨论了IEEE浮点除以零的语义。
答案 1 :(得分:4)
浮点变量实际上可以存储表示无穷大的值。 (这是math.h中定义的INFINITY
值。)但是没有无穷大的整数表示,所以唯一要做的就是失败。
答案 2 :(得分:4)
C标准定义了对算术类型的操作数除以零的行为是不确定的(例如,参见this在线C标准草案):
6.5.5乘法运算符
2每个操作数应具有算术类型。的操作数 %运算符应为整数类型。
5 /运算符的结果是除以 第一个操作数第二个; %运算符的结果是 余。在两个操作中,如果第二个操作数的值是 零,行为是不确定的。
此规则明确包含浮点值,因为术语arithmetic types表示整数值和浮点值:
6.2.5类型
18整数和浮点类型统称为算术 类型。
因此,您的两个示例实际上都是未定义的行为,每个编译器都可以自行指定如何处理您的语句。因此,如果编译器将零整数除法视为例外,则符合标准,而零浮点除法给出特殊值IProgress<String>
。注意:标准并未定义必须如此。