C++ C++;浮点精度
可能重复:C++ C++;浮点精度,c++,c,floating-point,precision,floating-accuracy,C++,C,Floating Point,Precision,Floating Accuracy,可能重复: 双a=0.3; 标准:计算精度(20); 计算机以二进制而不是十进制存储浮点数 许多十进制中看起来普通的数字,如0.3,在二进制中没有有限长度的精确表示。 因此,编译器选择具有精确二进制表示的最接近的数字,就像您为1/3编写0.33333 如果你加上许多浮点数,这些微小的差异就会叠加起来,你会得到意想不到的结果。并不是它的大小,只是在物理上不可能将“0.3”作为一个精确值存储在二进制浮点数中 获得“正确”结果的方法是不显示20位小数。要获得“正确”结果,请尝试 Wikipedia中
双a=0.3;
标准:计算精度(20);
计算机以二进制而不是十进制存储浮点数
许多十进制中看起来普通的数字,如0.3,在二进制中没有有限长度的精确表示。
因此,编译器选择具有精确二进制表示的最接近的数字,就像您为1/3
编写0.33333
如果你加上许多浮点数,这些微小的差异就会叠加起来,你会得到意想不到的结果。并不是它的大小,只是在物理上不可能将“0.3”作为一个精确值存储在二进制浮点数中
获得“正确”结果的方法是不显示20位小数。要获得“正确”结果,请尝试
Wikipedia中的任意精度算术库列表:
或
要获得正确的结果,请不要将精度设置为大于此数字类型的可用精度:
#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;
}
#包括
#包括
int main()
{
双a=0.3;
标准::计算精度(标准::数值限制::数字10);
std::cout这是为什么?
因为浮点数是以二进制存储的,其中0.3是0.01001100111001…重复就像1/3是0.333333…是以十进制重复的。当你写0.3
时,你实际上得到了0.2999999999999988897769753748434595763683319091796875(无限二进制表示四舍五入到53个有效数字)
请记住,对于为其设计浮点的应用程序,不能准确表示0.3并不是问题。浮点设计用于:
- 物理测量,通常仅测量到4个sig图,且从不超过15个
- 超越函数,如对数和三角函数,它们只是近似的
与其他误差源相比,二进制-十进制转换几乎不相关
现在,如果你在写金融软件,0.30美元意味着0.30美元,那就不同了。有一些十进制算术类是为这种情况设计的
在这种情况下如何得到正确的结果?
将精度限制在15位有效数字通常足以隐藏“噪声”数字。除非您确实需要确切的答案,否则这通常是最好的方法。去读一读。浮点问题需要仔细研究,以免犯危险的错误。要获得准确的值,请使用整数(或一些bignum lib)const int acc=100;int tmp,a=30/acc,b=0;for(char i=1;i+1表示数值_限制,这显然是不够的。我认为OP的关键答案是,“使用浮点无法得到正确的结果。”:)你得到了正确的结果。不可否认,这不是你所期望的结果。小数和任意精度的算术对于OP来说很可能是不必要的。也许你可以在第一段末尾添加:“…因为0.3的二进制表示的无限级数在某一点被截断,因为无限值不能存储在计算机上”。
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;
#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;
}