为了账号安全,请及时绑定邮箱和手机立即绑定

C ++浮点精度

/ 猿问

C ++浮点精度

C++ C
白衣染霜花 2019-10-21 14:55:29

double a = 0.3;

std::cout.precision(20);

std::cout << a << std::endl;

结果:0.2999999999999999889


double a, b;

a = 0.3;

b = 0;

for (char i = 1; i <= 50; i++) {

  b = b + a;

};

std::cout.precision(20);

std::cout << b << std::endl;

结果:15.000000000000014211


因此,“ a”小于应有的大小。但是,如果我们将“ a”取50倍,结果将大于应有的结果。


为什么是这样?以及在这种情况下如何获得正确的结果?


查看完整描述

3 回答

?
慕码人2483693

为了获得正确的结果,请不要将精度设置为大于此数字类型可用的精度:


#include <iostream>

#include <limits>

int main()

{

        double a = 0.3;

        std::cout.precision(std::numeric_limits<double>::digits10);

        std::cout << a << std::endl;

        double b = 0;

        for (char i = 1; i <= 50; i++) {

                  b = b + a;

        };

        std::cout.precision(std::numeric_limits<double>::digits10);

        std::cout << b << std::endl;

}

尽管如果该循环运行5000次迭代而不是50次迭代,则即使使用这种方法,也会显示累积的错误-这就是浮点数的工作方式。


查看完整回答
反对 回复 2019-10-21
?
拉风的咖菲猫

为什么是这样?

因为浮点数以二进制形式存储,所以0.3表示0.01001100110011001 ...重复,就像1/3表示0.333333 ...重复十进制。当您编写时0.3,您实际上得到0.299999999999999988897769753748434595763683319091796875(无穷大的二进制表示形式四舍五入为53个有效数字)。

请记住,对于设计了浮点的应用程序,可以精确地表示0.3并不是问题。浮点设计用于:

  • 物理测量,通常只能测量到4 sig图,而从不超过15。

  • 对数和三角函数之类的先验函数无论如何都只是近似的。

与其他错误源相比,二进制十进制转换与之无关。

现在,如果您要编写财务软件,那么$ 0.30 恰好是 $ 0.30,那就不一样了。有针对这种情况设计的十进制算术类。

以及在这种情况下如何获得正确的结果?

将精度限制为15个有效数字通常足以隐藏“噪声”数字。除非您确实需要确切的答案,否则通常这是最好的方法。


查看完整回答
反对 回复 2019-10-21
?
陪伴而非守候

计算机以二进制而不是十进制存储浮点数。


许多在十进制中看起来很普通的数字,例如0.3,都没有二进制形式的有限长度的精确表示。

因此,编译器会选择具有精确二进制表示形式的最接近的数字,就像您为编写0.33333的一样1⁄3。


如果添加许多浮点数,这些微小的差异加起来,就会得到意想不到的结果。


查看完整回答
反对 回复 2019-10-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信