请考虑以下事项:
#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,如果这很重要的话。
答案 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