演员表的标签问题

gclib issue with cast

这是我在写测试程序的时候发现的。我想知道这个问题在哪里。它是在 C 库 (printf)、clang 编译器还是 Mac 处理器中?我在 Mac 上使用 clang 编译了这个程序。这是短节目:

#include <stdio.h>

int main(void) {

    int num = 12;
    double temp = 0.0;

    temp = num/10.0;
    printf("%lf\n", temp);
    temp = temp - 1.0;
    printf("%lf\n", temp);
    temp = temp * 10.0;
    printf("%lf\n", temp);
    int new_num = temp;
    printf("%d\n", new_num);
    int cast_num =(int)temp;
    printf("%d\n", cast_num);

    return 0;
}

此程序适用于所有数字,但 num 以 12 结尾时除外。当 num 以 12 结尾时。new_num 和 cast num = 1 而不是应有的 2。如果将 num 设置为 22,则 new_num 和 cast_num = 2 就应该如此。即使 num = 11,10,13,14 等也能按预期工作...当 num 以 12 结尾时它不起作用。因此设置 num = 212,并将第 10 行替换为 temp=temp-21。并发生错误的结果。将 num 更改为 213,它按预期工作。

有人知道这个问题的本质吗?奇怪的是它只显示一个以 12 结尾的数字。

有什么想法吗?

A​​pple LLVM 版本 10.0.0 (clang-1000.10.44.4) 目标:x86_64-apple-darwin18.2.0 线程模型:posix

这是因为四舍五入问题。 2.000000 并不总是 2!

尝试以下操作:

temp = temp * 10.0;
printf("%.20lf\n", temp);

您可能会观察到,temp 略低于 2。因此转换为 int 会将其四舍五入为 1。

问题是,已经 1.2 (12/10.0) 不能精确表示为浮点数,所以第一个除法已经不完全是 1.2,而是少了一点。此错误会向下传播,直到您执行演员表。要解决此问题,例如在将其转换为 int.

之前使用 round() 在数学上进行舍入