gclib问题与演员表

时间:2019-01-04 12:34:19

标签: c casting posix

我在编写测试程序时发现了这一点。我想知道这个问题在哪里。是在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设置为2。如果num = 11,10,13,14等,即使按预期方式工作也是如此……当num以12结尾时,它不起作用。因此设置num = 212,并用temp = temp-21替换第10行。并且发生错误的结果。将num更改为213,即可正常使用。

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

有什么想法吗?

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

1 个答案:

答案 0 :(得分:0)

这是由于四舍五入问题。 2.000000并不总是2!

尝试以下操作:

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

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

问题是,已经1.212/10.0)不能精确地表示为浮点数,因此第一除法已经不是精确的1.2,而是要少一些。该错误会传播到您的演员表。要解决此问题,例如在将其强制转换为int之前,以数学上正确的方法round()进行舍入。