C语言中的浮点数很奇怪

问题描述

浮点在 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/ba 转换为 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