对于以下程序:

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    for (float a = 1.0; a < 10; a++)
        cout << std::setprecision(30) << 1.0/a << endl;
    return 0;
}

我收到以下输出:
1
0.5
0.333333333333333314829616256247
0.25
0.200000000000000011102230246252
0.166666666666666657414808128124
0.142857142857142849212692681249
0.125
0.111111111111111104943205418749

对于低位数字绝对不正确,尤其是对于1/3、1/5、1/7和1/9。事情在10 ^ -16左右才开始出错,我希望看到它看起来更像:
1
0.5
0.333333333333333333333333333333
0.25
0.2
0.166666666666666666666666666666
0.142857142857142857142857142857
0.125
0.111111111111111111111111111111

这是float类的继承缺陷吗?有没有办法克服这个问题并进行适当的划分?是否有用于执行精确十进制运算的特殊数据类型?在我的示例中,我只是在做愚蠢或错误的事情吗?

最佳答案

即使使用浮点数或 double 浮点数,计算机也无法表示很多数字。 1/3或.3重复是这些数字之一。因此,它会尽力而为,这就是您得到的结果。

请参阅http://floating-point-gui.de/或google float精度,有关此主题有很多信息(包括许多SO问题)。

要回答您的问题-是的,这是float类和double类的固有限制。某些数学程序(MathCAD,可能是Mathematica)可以执行“符号”数学运算,从而可以计算“正确”答案。在很多情况下,即使在非常复杂的计算中,也可以管理舍入误差,从而使前6-8位小数位正确。但是,相反的情况也是如此-可以构造幼稚的计算来返回非常错误的答案。

对于诸如整数除法之类的小问题,您将获得可观的小数位数精度(可能是4-6位)。如果您使用 double 浮点数,则可能会达到8。如果您需要更多...好吧,我将开始质疑为什么要这么多小数位。

07-24 09:45
查看更多