C语言中的浮点数很奇怪
Floating point is very weird in C language
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("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", 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);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
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 应该打印双精度,但您传递的是整数。这是未定义的行为。在这种情况下,它通过打印先前传递的参数的“remains”来表达自己。在此修改示例中,它清晰可见。但当然它是一个 UB,程序的行为可以完全不同。还要记住,整数除法的结果也是一个整数。 C 和 C++ 中的 30/16 == 1
(double)(a/b)
是 1.0,因为它将整数除法的结果转换为 double
(double)a/b
将 a
转换为双精度,然后进行双除法。
#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", a/b);
printf("result1 : %f \n", (double)a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", 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);
printf("result2 : %f \n", 0.0);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", (double)a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", (double)(a/b));
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", 0.0);
printf("result2 : %f \n", 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
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("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", 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);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
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 应该打印双精度,但您传递的是整数。这是未定义的行为。在这种情况下,它通过打印先前传递的参数的“remains”来表达自己。在此修改示例中,它清晰可见。但当然它是一个 UB,程序的行为可以完全不同。还要记住,整数除法的结果也是一个整数。 C 和 C++ 中的 30/16 == 1
(double)(a/b)
是 1.0,因为它将整数除法的结果转换为 double
(double)a/b
将 a
转换为双精度,然后进行双除法。
#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", a/b);
printf("result1 : %f \n", (double)a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", a/b);
printf("result1 : %f \n", 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);
printf("result2 : %f \n", 0.0);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", (double)a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", (double)(a/b));
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", a/b);
printf("result2 : %f \n", 0.0);
printf("result2 : %f \n", 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