问题描述
浮点在 C 语言中很奇怪。我知道它通常用作 (float)a/b。不过,我很好奇下面代码现象的主要原因和原因是什么。
#include <stdio.h>
int main(void)
{
int a=30,b=16;
double divresult;
divresult = a/b;
printf("result1 : %f \n",a/b);
printf("result1 : %f \n",a/b);
printf("divresult : %f \n",divresult);
printf("result2 : %f \n",a/b);
printf("result2 : %f \n",a/b);
return 0;
}
result1 : 0.000000
result1 : 0.000000
result1 : 0.000000
result1 : 0.000000
result1 : 0.000000
result1 : 0.000000
result1 : 0.000000
result1 : 0.000000
result1 : 0.000000
divresult : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
为什么会这样?我真的无法理解。一般来说,我们知道计算机无法准确表示浮点数。但在这种情况下,似乎有一些模式。 “divresult printf”前后值的变化是怎么出现的?
解决方法
Printf 应该打印 double 但你传递的是 integer。这是未定义的行为。在这种情况下,它通过打印前一个传递参数的“剩余”来表达自己。在这个修改后的例子中,它清晰可见。但当然它是一个 UB,程序的行为可以完全不同。还要记住整数除法的结果也是整数。 C 和 C++ 中的 30/16 == 1
(double)(a/b)
是 1.0,因为它将整数除法的结果转换为 double
(double)a/b
将 a
转换为 double,然后进行双除。
#include <stdio.h>
int main(void)
{
int a=30,b=16;
double divresult;
divresult = a/b;
printf("result1 : %f \n",(double)(a/b));
printf("result1 : %f \n",a/b);
printf("result1 : %f \n",(double)a/b);
printf("result1 : %f \n",a/b);
printf("divresult : %f \n",divresult);
printf("result2 : %f \n",a/b);
printf("result2 : %f \n",0.0);
printf("result2 : %f \n",(double)a/b);
printf("result2 : %f \n",(double)(a/b));
printf("result2 : %f \n",a/b);
return 0;
}
结果
x86-64 gcc 10.2
Program returned: 0
Program stdout
result1 : 1.000000
result1 : 1.000000
result1 : 1.000000
result1 : 1.875000
result1 : 1.875000
result1 : 1.875000
result1 : 1.875000
result1 : 1.875000
result1 : 1.875000
divresult : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 0.000000
result2 : 0.000000
result2 : 0.000000
result2 : 1.875000
result2 : 1.875000
result2 : 1.875000
result2 : 1.875000
result2 : 1.000000
result2 : 1.000000
result2 : 1.000000
result2 : 0.000000
result2 : 0.000000
result2 : 0.000000