用C除以零

时间:2019-02-01 23:31:37

标签: c operands

当我编译该程序:

#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时为什么返回错误?

3 个答案:

答案 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>。注意:标准并未定义必须如此。