考不好不改名 发表于 2024-9-5 22:18:18

一个关于 double 和 float 在保留小数位数时的玄学问题

关于下面这段代码:
#include<bits/stdc++.h>

using namespace std;

int main(){
      float a;
      double b;
      
      cin >> a >> b;
      printf("%.3f %.3lf\n", a, b);
      
      return 0;
}我们先输入1.2345 1.2345得到输出
1.235 1.234可以见到,使用 float 的变量在保留小数位数时进位了而 double 则没有。
但是我们再试着输入
1.2346 1.2346得到输出
1.235 1.235这时两个变量都进行了进位。

然而我们知道(如果我没记错的话),%.3f 或 %.3lf 应该是“四舍五入”的,但现在看貌似却是 float 是四舍五入而 double 是“五舍六入”?

这到底是怎么回事?编译器问题?标准问题?历史遗留问题?

求解答

FishC 发表于 2024-9-5 22:46:29

这是一个关于浮点数精度和表示的问题。其实,说到底这是由于浮点数在存储时的精度限制所导致的现象。

1. **浮点数表示**:
   - `float` 通常使用32位来存储数据,因而它的精度和有效位数相对较低。
   - `double` 通常使用64位来存储数据,所以它的精度和有效位数相对较高。

2. **舍入误差**:
   - 当你输入 `1.2345` 和 `1.2346` 时,由于浮点数的表示方式,这些值在内存中实际上不会精确等于你输入的值,它们会被近似为一个最接近的可表示浮点数。
   - 例如,当你输入 `1.2345` 给 `float`,它可能被实际存储为比 `1.2345` 稍微大一点的一个值,而这个值在打印时就会显示为 `1.235`。
   - 对于 `double`,因为它的精度更高,所以在输入 `1.2345` 时它能够更精准地接近该数值,因此 `1.2345` 在 `double` 中比较接近,于是打印时显得没有进位。

3. **不同的输入值对结果的影响**:
   - 当输入 `1.2346` 时,不论是 `float` 还是 `double`,它们都接近一个相对准确的数值,这样在打印时都显示进位后的数值 `1.235`。

4. **关于格式化和舍入**:
   - `%.3f` 和 `%.3lf` 格式化输出时,基本上都是遵循四舍五入的原则。
   - 只不过由于 `float` 和 `double` 在数字表示上的差异,导致实际输出的结果有所不同。

所以,这并不是一个编译器或者标准的问题,而是浮点数本身在计算机中的表示和精度带来的差异。你应该更关注的是浮点数的表示误差,而不是表面上看起来的“玄学”现象。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 一个关于 double 和 float 在保留小数位数时的玄学问题