将 double 转换为 int 仅适用于常量

kil*_*129 1 c floating-point printf integer-arithmetic conversion-specifier

我在 C 中发现了一种奇怪的(对我来说)行为。int如果这是一个基本问题,请注意,但我无法找到为什么以下代码会产生意外结果的答案。

#include <stdio.h>
int main(void)
{
    printf("1000 * 0.1 = %d\n", (1000 * 0.1));
    printf("1000 * (10/100) = %d\n", (1000 * (10/100)));
    printf("(int)1000 * 0.1 = %d\n", (int)(1000 * 0.1));
    printf("(int)1000 * (10/100) = %d\n", (int)(1000 * (10/100)));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

两者的结果是-O0相同-O3的:

1000 * 0.1 = -957043896
1000 * (10/100) = 0
(int)1000 * 0.1 = 100
(int)1000 * (10/100) = 0
Run Code Online (Sandbox Code Playgroud)

我预计前两个结果是无意义的(我不知道为什么,但我预计将 double 传递给 int 参数不应该起作用)。然而3和4之间的差异让我感到困惑。我期望(10/100)在编译时计算并呈现与 3 相同的结果。

有人可以向我解释为什么会发生这样的结果,以及这里进行基于整数的除法的正确/安全方法是什么?

pmg*_*pmg 5

printf("1000 * 0.1 = %d\n", (1000 * 0.1));
//                           int    double
Run Code Online (Sandbox Code Playgroud)

int * double给出一个双倍。您正在尝试打印double带有未定义行为"%d"(通常写为 UB)的a 。尝试printf("1000 * 0.1 = %f\n", 1000 * 0.1);

printf("1000 * (10/100) = %d\n", (1000 * (10/100)));
//                                int    int int
Run Code Online (Sandbox Code Playgroud)

int / int进行整数除法,不带小数。10/100产量0(以及 的余数10

printf("(int)1000 * 0.1 = %d\n", (int)(1000 * 0.1));
//                                     int    double
Run Code Online (Sandbox Code Playgroud)

double100.0会自然地转换int并打印。请注意,可能1000 * 0.1会生成99.999999635264318将转换为99

printf("(int)1000 * (10/100) = %d\n", (int)(1000 * (10/100)));
//                                          int    int int
Run Code Online (Sandbox Code Playgroud)

10/100整数除法...0在这种情况下,与上面的第二条语句相同。