GCC编译时分错误

kar*_*hta 2 c compiler-construction gcc

有人可以解释这种行为吗?

test.c的:

#include <stdio.h>

int main(void)
{
    printf("%d, %d\n", (int) (300.6000/0.05000), (int) (300.65000/0.05000));
    printf("%f, %f\n", (300.6000/0.05000), (300.65000/0.05000));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

$ gcc test.c

$ ./a.out
6012, 6012
6012.000000, 6013.000000
Run Code Online (Sandbox Code Playgroud)

我检查了汇编代码,它将第一个printf的参数都设置为6012,所以它似乎是一个编译时错误.

Mat*_*hen 10

#include <stdio.h>

int main(void)
{
    printf("%d, %d\n", (int) (300.6000/0.05000), (int) (300.65000/0.05000));
    printf("%.20f %.20f\n", (300.6000/0.05000), (300.65000/0.05000));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它应该更清楚.第二个的值(在浮点除法之后,这不是精确的)是~6012.9999999999991,所以当你用(int)截断它时,gcc足够聪明,可以在编译时输入6012.

当您打印浮动时,printf默认将它们格式化为仅显示6位精度,这意味着第二个打印为6013.000000.


Joh*_*ica 7

printf()打印时舍入浮点数.如果您添加更多精度,您可以看到发生了什么:

$ cat gccfloat.c
#include <stdio.h>

int main(void)
{
    printf("%d, %d\n", (int) (300.6000/0.05000), (int) (300.65000/0.05000));
    printf("%.15f, %.15f\n", (300.6000/0.05000), (300.65000/0.05000));
    return 0;
}

$ ./gccfloat
6012, 6012
6012.000000000000000, 6012.999999999999091
Run Code Online (Sandbox Code Playgroud)