【问题标题】:Inconsistencies with double data type in C++C++ 中的双精度数据类型不一致
【发布时间】:2011-01-23 21:55:31
【问题描述】:

这可能是我刚刚遗漏的非常简单的东西,但是我在使用双精度数据类型时遇到了问题。它指出here C++ 中的 double 精确到 ~15 位。然而在代码中:

double n = pow(2,1000);
cout << fixed << setprecision(0) << n << endl;

n 存储 2^1000 的精确值,根据 WolframAlpha,它是 302 位十进制数字。然而,当我尝试计算 100!时,使用以下函数:

   double factorial(int number)
{
    double product = 1.0;
    for (int i = 1; i <= number; i++){product*=i;}
    return product;
}

第 16 位开始出现错误。有人可以解释一下这种行为,并为我提供某种解决方案。

谢谢

【问题讨论】:

  • 按照设计没有什么可以解决的。
  • 在网络上搜索“IEEE 754”并阅读
  • 不,该页面根本没有说明 double 是准确的。它只是说它可以跨越多少数字。准确性就是浮点的工作原理。
  • 首先您说“这里声明 C++ 中的双精度数精确到约 15 位数字。”然后你说“第 16 位开始出现错误。有人可以解释一下这种行为”。你不是已经回答了你自己的问题吗?大致可以说,双精度数据类型可以“有效”存储约 15 位数字,但如果其中很多是零,它可以存储更多。
  • @njak32 你说得对,它是一个 302 位数字,在十进制系统中几乎没有任何零组。但是由于计算机使用二进制系统,所以数字 2^1000 只是“1”后面跟着一千个零。

标签: c++ types double


【解决方案1】:

您最终需要阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic 中的基础知识。浮点硬件最常见的标准通常是 IEEE 754;当前版本是 2008 年的,但大多数 CPU 没有实现 2008 版中的新十进制算法。

但是,浮点数(doublefloat)使用固定大小的尾数(小数部分)和指数(2 的幂)存储该值的近似值。指数的动态范围使得可以表示的值范围从十进制的大约 10-300 到 10+300,大约有 16 个有效(十进制)数字的准确性。人们不断尝试打印比存储更多的数字,并且当他们这样做时会得到有趣且依赖于机器(和依赖于库)的结果。

因此,您所看到的内容是使用固定精度值的计算机上浮点运算的本质所固有的。如果您需要更高的精度,则需要使用任意精度库之一 - 其中有很多可用。

【讨论】:

    【解决方案2】:

    double 实际上在其内部表示中存储了要应用于 2 的指数。所以它当然可以准确地存储 2^1000。但请尝试在其中添加 1。

    【讨论】:

      【解决方案3】:

      IEEE 754 给出了一种存储浮点数据的算法。计算机有有限的位数来存储无限的数字,因此在存储数字时会引入错误。

      在这种表示形式中,表示的数字越大(越大 == 与零的绝对距离),精度空间就越小。可能在那个时候你会看到精度的损失,当你得到更大的数字时,它会有更大的精度损失。

      【讨论】:

      • 废话!这是浮点数。与零的距离与它有什么关系?
      • @大卫:一切?数字离零越远,与下一个可表示数字的增量就越大。
      • @Fred 那么 300 位小数的数字是如何精确表示的呢?这种所谓的逻辑是不可能的,因为距离零的距离太远,所有的精度都已经丢失了。
      • @David:当您在double 中获得 1*2^300 时,您不知道它实际上是二进制 1 后跟 300 个零还是 1 后跟 50零,然后全是。类型的精度不允许您知道;如果它是一个 1 后跟 300 个零,那么你已经很幸运了(因为你的结果被准确地表示了),但你甚至不确定它(因为你有一个 +-2^something 不确定性)。
      • 我想这取决于你是在做加法还是乘法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 1970-01-01
      • 2012-07-05
      • 2018-10-19
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多