【问题标题】:C++ not truncating doubles?C ++不截断双精度数?
【发布时间】:2019-03-13 18:49:53
【问题描述】:

My code:

以下代码运行结果:

#include <cstdio>

//i define printBits elsewhere but that's not relevant to my question
void printBits(const float f);
void printBits(const double f);

int main(int argc, char **argv) {
  float f=4.2;
  double d=4.2;
  printf("float: %20.20f\n",f);
  printBits(f);
  printf("double: %50.50f\n",d);
  printBits(d);

 return 0;
}

是:

float: 4.19999980926513671875
0    10000001 00001100110011001100110

double: 4.20000000000000017763568394002504646778106689453125
0 10000000001 0000110011001100110011001100110011001100110011001101

请注意我如何将f 和d 都设置为4.2,但float 值略小于4.2,double 值略大于4.2。我明白为什么浮点值小于 4.2; 4.2 值被截断为小于 4.2 的值 ~2^-21。但是,我不明白为什么双精度值比 4.2 略大于。我认为 float 和 double 值只会截断,但似乎 double 值是向上舍入而不是向下舍入。

一般来说,浮点数和双精度数是否舍入到最接近的可表示值?浮点数和双精度数是否不同?我已尝试搜索此内容,但找不到任何相关内容。

【问题讨论】:

  • 如果您包含&lt;cstdio&gt;,则您使用的是 C++,而不是 C。此外,如果您有重载函数,那么您肯定使用的是 C++ 而不是 C。不要标记错误语言——它会激怒人们并导致投票失败。
  • 希望有人会详细解释 4.2 如何不能完全表示为二进制浮点,但这就是原因。 stackoverflow.com/questions/588004/…
  • 有一个关于 SO 的标准交叉引用问答 - Is floating-point math broken? 答案是否定的,但它不一定按您期望的方式工作。

标签: c++ floating-point double precision floating-accuracy


【解决方案1】:

浮点值不会截断,它们会四舍五入到最接近的可表示值。您发现了一个有趣的示例,其中根据浮点的大小进行舍入的方向不同,但这并不少见;您可以预期舍入大约有 50% 的时间上升,而下降 50% 的时间,其中一些值是完全可表示的,并且根本没有四舍五入。例如 4.25 是准确的。

【讨论】:

  • 我认为易于可视化的示例可能很有用。例如,如果float 可以表示 0、¼、½、¾ 和 1,而 double 可以表示 0、⅛、¼、⅜、½、⅝、¾、⅞ 和 1,则将 .6 转换为float 将向下舍入为 ½(接近 0.5 而不是 0.75),但将 0.6 转换为 double 会向上舍入为 ⅝(接近 0.625 而不是 0.5)。
猜你喜欢
  • 1970-01-01
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-18
  • 1970-01-01
  • 1970-01-01
  • 2014-08-16
相关资源
最近更新 更多