【问题标题】:Error due to limited precision of float and double由于浮点数和双精度数有限而导致的错误
【发布时间】:2011-10-09 07:59:44
【问题描述】:

在 C++ 中,由于 float 和 double 的精度有限,我使用以下代码计算出误差的数量级:

 float n=1;
 float dec  = 1;

 while(n!=(n-dec)) {
    dec = dec/10;
 }
 cout << dec << endl;

(在 double 情况下,我所做的只是在第 1 行和第 2 行用 double 交换浮点数)

现在,当我在 Unix 系统上使用 g++ 编译和运行它时,结果是

Float  10^-8
Double 10^-17

但是,当我在 Windows 7 上使用 MinGW 编译和运行它时,结果是

Float  10^-20
Double 10^-20

这是什么原因?

【问题讨论】:

  • 某事告诉我,MinGW 以 80 位扩展精度存储 n!=(n-dec) 的中间体。 10^-20 大约是 80 位 FP 的 epsilon...

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


【解决方案1】:

我想我会将我的评论作为答案并对其进行扩展。 这是我的假设,我可能错了。

Windows 上的 MinGW 可能试图通过将表达式的中间体提升到 x86 的完整 80 位精度来保持精度。

因此,表达式 n != (n-dec) 的两边都被计算为 64 位精度(80 位 FP 具有 64 位尾数)。

2^-64 ~ 10^-20

所以这些数字是有意义的。

Visual Studio 也(默认情况下)将促进中间体。但只能达到双精度。

【讨论】:

  • GCC 中使用的优化标志也可能会改变输出,因为它会改变处理浮点数的方式。还要注意,这里不仅仅是编译器,还有芯片本身以及它使用的浮点模式。编译器还可以为浮点生成特殊的截断命令。变量很多,但是是的,你的答案基本上是正确的。
  • @edA-qa mort-ora-y:同意。我想了更多。所需要的只是使 FP 模式具有扩展精度。代码也足够小,不会溢出 x87 寄存器。所以不会发生对商店的四舍五入。
【解决方案2】:

为什么不在两个操作系统中检查 float 和 double 的大小?

【讨论】:

  • 在 W7 上,浮点 = 32 位,双精度 = 64 位(使用 sizeof())。我如何将其与上面的发现联系起来?
【解决方案3】:

这只是说明不同的环境对 float 和 double 使用不同的大小。

根据 C++ 规范,double 必须至少与 float 一样大。如果您想了解系统上的类型有多大,请使用sizeof

您的测试似乎表明 g++ 对 float 和 double 使用不同的大小(分别为 32 位和 64 位),而 Windows 系统上的 MinGW32 对两者使用相同的大小。这两个版本都符合标准,一般都不能依赖任何行为。

【讨论】:

  • 在下面查看我对suresh 帖子的评论。我的 Windows 系统上用于 float 和 double 的尺寸是不同的。
  • @Agentlien:在两个系统上,float 是 4 个字节,double 是 8 个字节。关闭优化后,MinGW 的行为就像 Unix。
猜你喜欢
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多