问题遇到的现象和发生背景
我写了一个保留小数点后一位有效数字的宏定义,不进行四舍五入处理,如下所示:
#define PRECISION_1(x) (((double)((int32_t)((x) * 10))) / 10)
问题相关代码,请勿粘贴截图
测试用例如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define PRECISION_1(x) (((double)((int32_t)((x) * 10))) / 10)
int main()
{
printf("result=%lf\n", PRECISION_1(3.1415926));
double temp = 0.100000;
printf("temp=%lf, result=%lf\n", temp, PRECISION_1(temp)); // --1
printf("result=%lf\n", PRECISION_1(0.100000));
printf("result=%lf\n", PRECISION_1(1677721.400000-1677721.300000)); // --2
double x = 1677721.4-1677721.3;
// float x = 1677721.4-1677721.3; //改成float类型,结果又是正确的,离谱啊!
printf("x=%lf, result=%lf\n", x, PRECISION_1(x)); // --3
return 0;
}
运行结果及报错内容
使用 GCC 编译器进行编译:gcc test.c -o test (可以加 -std=c99 或 -std=c11)
运行结果如下:./test
result=3.100000
temp=0.100000, result=0.100000
result=0.100000
result=0.000000
x=0.100000, result=0.000000
可以看到上述代码第1处、第2处和第3处的 result 输出结果是有区别的,让人匪夷所思!
我的解答思路和尝试过的方法
我对 test.c 源码进行预处理后:gcc -E test.c -o test.i,打开 test.i 文件,关键代码如下:
......
typedef int int32_t;
......
# 7 "test3.c"
int main()
{
printf("result=%lf\n", (((double)((int32_t)((3.1415926) * 10))) / 10));
double temp = 0.100000;
printf("temp=%lf, result=%lf\n", temp, (((double)((int32_t)((temp) * 10))) / 10));
printf("result=%lf\n", (((double)((int32_t)((0.100000) * 10))) / 10));
printf("result=%lf\n", (((double)((int32_t)((1677721.400000-1677721.300000) * 10))) / 10));
double x = 1677721.4-1677721.3;
printf("x=%lf, result=%lf\n", x, (((double)((int32_t)((x) * 10))) / 10));
return 0;
}
我想要达到的结果
我这里不明白的是,为什么上述代码第1处、第2处和第3处的运行结果一个是0.100000,而另外两个却是0.000000,这让我感到很奇怪!
变量temp和x的值都是0.100000,PRECISION_1(temp)的结果是0.100000,而PRECISION_1(x)的值却是0.000000,离大谱啊!
还请C/C++语言开发们帮忙解答一下呀,感谢了!