【问题标题】:Floating point is very weird in C language [duplicate]C语言中的浮点数很奇怪[重复]
【发布时间】:2021-05-11 06:41:59
【问题描述】:

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”前后值的变化是如何出现的?

【问题讨论】:

  • 你为什么要标记 c++?
  • a/b 产生一个整数,但您尝试使用%f 打印它
  • 从编译器读取警告
  • %f 是浮点数的格式说明符,整数除法得到整数。
  • @πάνταῥεῖ 这是错误的副本。问题的情况完全不同

标签: c printf computer-science


【解决方案1】:

Printf 应该打印双精度,但您传递整数。这是未定义的行为。在这种情况下,它通过打印传递的前一个参数的“剩余”来表达自己。在这个修改后的示例中,它清晰可见。但当然它是一个 UB,程序的行为可能完全不同。还要记住整数除法的结果也是一个整数。 30/16 == 1 在 C 和 C++ 中

(double)(a/b) 是 1.0,因为它将整数除法的结果转换为双精度

(double)a/ba 转换为双精度然后进行双除法。

#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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2013-07-16
    相关资源
    最近更新 更多