关于操作数:在C中除以零

Dividing by zero in C

当我编译程序时:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(void)
{
    int x, y = 0;

    x = 1 / y;
    printf("x = %d
"
, x);
    return 0;
}

它给出了"浮点异常(核心转储)"

但是,当我编译时:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(void)
{
    double x, y = 0;

    x = 1 / y;
    printf("x = %f
"
, x);
    return 0;
}

它打印"x = inf"

如果你使用double,为什么它将x作为无限值返回,但如果你使用int则会返回错误?


C标准明确指出除以零对于整数或浮点操作数具有未定义的行为。

C11 6.5.5第5段:

The result of the / operator is the quotient from the division of the
first operand by the second; the result of the % operator is the
remainder. In both operations, if the value of the second operand is
zero, the behavior is undefined.

未定义的行为意味着标准没有说明发生的事情。它可能产生一个有意义或无意义的结果,它可能会崩溃,或者它可以像标准的笑话一样,让恶魔飞出你的鼻子。 (当然后者不会发生,但如果确实如此,它就不会违反C标准。)

与整数类型不同,浮点类型通常具有不表示数字的特殊值。 IEEE浮点标准规定,除以零可以产生无穷大的结果,这正是您的实现所做的。整数没有"无穷大"值。 (注意,C实现可能符合也可能不符合IEEE浮点标准。)

这个问题讨论了IEEE浮点中除零的语义。


C标准定义了对算术类型操作数的除零行为是未定义的(参见,例如,此在线C标准草案):

6.5.5 Multiplicative operators

2 Each of the operands shall have arithmetic type. The operands of the
% operator shall have integer type.

5 The result of the / operator is the quotient from the division of
the first operand by the second; the result of the % operator is the
remainder. In both operations, if the value of the second operand is
zero, the behavior is undefined.

此规则明确包含浮点值,因为术语算术类型表示整数值和浮点值:

6.2.5 Types

18 Integer and floating types are collectively called arithmetic
types.

因此,您的两个示例实际上都是未定义的行为,并且每个编译器可以自己指定如何处理您的语句。因此,如果编译器将整数除零视为异常,则它是符合标准的,而浮点除零则给出特殊值inf。注意:标准没有定义必须如此。


浮点变量实际上可以存储表示无穷大的值。 (它是在math.h中定义的值INFINITY)但是没有无穷大的整数表示,所以唯一要做的就是失败。