c ++不正确的浮点运算 [英] c++ incorrect floating point arithmetic

查看:153
本文介绍了c ++不正确的浮点运算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于以下程序:

#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我会期望看到更多类似:

Which is definitely not right right for the lower place digits, particularly with respect to 1/3,1/5,1/7, and 1/9. things just start going wrong around 10^-16 I would expect to see out put more resembling:

1
0.5
0.333333333333333333333333333333
0.25
0.2
0.166666666666666666666666666666
0.142857142857142857142857142857
0.125
0.111111111111111111111111111111

这是float类中的继承缺陷吗?有办法克服这个和有适当的分裂吗?是否有一个特殊的数据类型进行精确的小数运算?

Is this an inherit flaw in the float class? Is there a way to overcome this and have proper division? Is there a special datatype for doing precise decimal operations? Am I just doing something stupid or wrong in my example?

推荐答案

有很多数字,计算机无法代表,即使你使用float或double-precision float。 1/3或.3重复,是这些数字之一。

There are a lot of numbers that computers cannot represent, even if you use float or double-precision float. 1/3, or .3 repeating, is one of those numbers. So it just does the best it can, which is the result you get.

请参阅 http://floating-point-gui.de/ ,或google的浮动精度,这里有很多信息(包括许多SO问题)。

See http://floating-point-gui.de/, or google float precision, there's a ton of info out there (including many SO questions) on this subject.

回答你的问题 - 是的,这是float类和double类的固有限制。一些数学程序(MathCAD,可能是Mathematica)可以做符号数学,这允许计算正确的答案。在许多情况下,可以管理舍入误差,甚至在真正复杂的计算上,使得前6-8个小数位是正确的。但是,相反的情况是正确的,以及可以构造返回非常不正确的答案的幼稚计算。

To answer your questions -- yes, this is an inherent limitation in both the float class and the double class. Some mathematical programs (MathCAD, probably Mathematica) can do "symbolic" math, which allows calculation of the "correct" answers. In many cases, the round-off error can be managed, even over really complex computations, such that the top 6-8 decimal places are correct. However, the opposite is true as well -- naive computations can be constructed that return wildly incorrect answers.

对于像整数的除法这样的小问题,你会得到一个正确的小数位数精度(也许4-6位数)。如果你使用双精度浮点数,这将上升到也许8.如果你需要更多...好,我会开始质疑你为什么要这么多的小数位。

For small problems like division of whole numbers, you'll get a decent number of decimal place accuracy (maybe 4-6 places). If you use double precision floats, that will go up to maybe 8. If you need more... well, I'd start questioning why you want that many decimal places.

这篇关于c ++不正确的浮点运算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆