我正在处理一个使用非常少量的10 ^ -15到10 ^ -25的订单的代码。我尝试使用double
和long double
,但由于0.000000000000000000001
四舍五入为0
,或者0.00000000000000002
之类的数字表示为{{},我的回答错误1}}。
由于即使是1/1000000的一小部分在我的最终答案中产生巨大差异,是否有适当的解决方案?
0.00000000000000001999999999999
预期输出应为:
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <iomanip>
using namespace std;
int main()
{
double sum, a, b, c,d;
a=1;
b=1*pow(10,-15);
c=2*pow(10,-14);
d=3*pow(10,-14);
sum=a+b+c+d;
cout<<fixed;
cout<<setprecision(30);
cout<<" a : "<<a<<endl<<" b : "<<b<<endl<<" c : "<<c<<endl
<<" d : "<<d<<endl;
cout<<" sum : "<<sum<<endl<<endl;
a=a/sum;
b=b/sum;
c=c/sum;
d=d/sum;
sum=a+b+c+d;
cout<<" a : "<<a<<endl<<" b : "<<b<<endl<<" c : "<<c<<endl
<<" d : "<<d<<endl;
cout<<" sum2: "<<sum<< endl;
return 0;
}
但是,我得到的输出是:
a : 1.000000000000000000000000000000
b : 0.000000000000001000000000000000
c : 0.000000000000020000000000000000
d : 0.000000000000030000000000000000
sum : 1.000000000000051000000000000000
a : 1.000000000000000000000000000000
b : 0.000000000000001000000000000000
c : 0.000000000000020000000000000000
d : 0.000000000000030000000000000000
sum1: 1.000000000000051000000000000000
我尝试了a : 1.000000000000000000000000000000
b : 0.000000000000001000000000000000
c : 0.000000000000020000000000000000
d : 0.000000000000029999999999999998
sum : 1.000000000000051100000000000000
a : 0.999999999999998787999878998887
b : 0.000000000000000999999997897899
c : 0.000000000000019999999999999458
d : 0.000000000000029999999999996589
sum1: 0.999999999999989000000000000000
,double
甚至long double
,但我得到的输出相似。
答案 0 :(得分:1)
正如您所注意到的那样,发生这种情况是因为数字无法以二进制形式准确表示,并且在某种程度上被舍入。
现在,由于您使用boost
标记对其进行了标记,因此提升boost.multiprecision完全符合您的要求。它提供cpp_dec_float_50
数据类型,可确保精确计算最多50个十进制数字。它可以用作任何其他类型:
typedef boost::multiprecision::cpp_dec_float_50 value_type;
value_type v1 = 1;
value_type v2 = 3;
value_type v3 = v1 / v2;
根据boost doc,保证只输出精确的位:
cpp_dec_float_50 seventh = cpp_dec_float_50(1) / 7;
cpp_dec_float_50 circumference = boost::math::constants::pi<cpp_dec_float_50>() * 2 * seventh;
std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10);
std::cout << circumference << std::endl;
答案 1 :(得分:0)
我打赌你在写:
long double sum, a, b, c,d;
a=1;
b=1*pow(10,-15);
c=2*pow(10,-14);
d=3*pow(10,-14);
问题是pow
将是pow的 double 版本 - 而不是long double版本。你需要强制其中一个参数加倍:
long double sum, a, b, c,d;
a=1;
b=1*pow(10.0L,-15);
c=2*pow(10.0L,-14);
d=3*pow(10.0L,-14);