std :: floor函数的不同值,用于具有相同值但不同类型的参数

时间:2011-08-11 19:22:50

标签: c++ logging floor

请考虑以下事项:

#include <iostream>
#include <cmath>
int main()
{
  using std::cout;
  using std::endl;

  const long double be2 = std::log(2);
  cout << std::log(8.0) / be2 << ", " << std::floor(std::log(8.0) / be2)
      << endl;

  cout << std::log(8.0L) / be2 << ", " << std::floor(std::log(8.0L) / be2)
      << endl;
}

输出

  3, 2
  3, 3

为什么输出会有所不同?我在这里缺少什么?

此处还有指向键盘的链接:http://codepad.org/baLtYrmy

我在linux上使用gcc 4.5,如果这很重要的话。

3 个答案:

答案 0 :(得分:4)

当我添加此内容时:

cout.precision(40);

我得到了这个输出:

2.999999999999999839754918906642444653698, 2
3.00000000000000010039712117215771058909, 3

您正在打印两个非常接近但不完全等于3.0的值。 std::floor的本质是它的结果可能因非常接近的值而不同(数学上,它是一个不连续的函数)。

答案 1 :(得分:2)

#include <iostream>
#include <cmath>
#include <iomanip>

int main()
{
  using std::cout;
  using std::endl;

  const long double be2 = std::log(2);

  cout << setprecision (50)<<std::log(8.0)<<"\n";
  cout << setprecision (50)<<std::log(8.0L)<<"\n";
  cout << setprecision (50)<<std::log(8.0) / be2 << ", " << std::floor(std::log(8.0) / be2)
       << endl;
  cout << setprecision (50)<< std::log(8.0L) / be2 << ", " << std::floor(std::log(8.0L) / be2)
       << endl;

  return 0;
}

输出结果为:

2.0794415416798357476579894864698871970176696777344
2.0794415416798359282860714225549259026593063026667
2.9999999999999998397549189066424446536984760314226, 2
3.0000000000000001003971211721577105890901293605566, 3

如果检查输出 here ,您会注意到两个输出的精度略有差异。这些舍入误差通常会对浮动和放大器的操作产生影响。在执行floor()时加倍,并且显示的结果不是人们认为的结果。

重要的是要记住两个属性精确&amp;当你使用浮点数或双数字时,舍入

您可能希望在我的回答 here 中详细了解相关内容,同样的推理也适用于此。

答案 2 :(得分:2)

扩展Als所说的话 -

在第一种情况下,您将8字节双精度值除以16字节长的双精度值。在第二种情况下,您将一个16字节长的双精度数除以一个16字节长的双精度数。这导致非常小的舍入误差,可以在这里看到:

cout << std::setprecision(20) << (std::log(8.0) / be2) << std::endl;
cout << std::setprecision(20) << (std::log(8.0L) / be2) << std::endl;

产生:

2.9999999999999998398
3.0000000000000001004

编辑说:在这种情况下,sizeof是你的朋友(要查看精度的差异):

sizeof(std::log(8.0));  // 8
sizeof(std::log(8.0L)); // 16
sizeof(be2);            // 16