私は10^-15から10^-25までの非常に小さな数を使用するコードを扱っています。私はdouble
とlong double
を使ってみましたが、0.000000000000000000001
が0
に丸められているか、0.00000000000000002
のような数字が0.00000000000000001999999999999
のように誤った答えが出ました。C++非常に小さい浮動小数点数、preciscion
1/1000000という小さな割合でも最終回答に大きな違いがあるので、適切な修正がありますか?
#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
私はlong double
、double
を試してみましたが、でもboost_dec_float
が、私が手出力があります類似。
構造体を番号の独自の表現にします。指数関数的には短く、残りは二倍になります。 このような小さな番号で作業しないようにユニットを変更することはできますか? – UKMonkey
私はこれが重複ではないと主張します。 OPは正確に何が起きているのかを正確に知り、精度を高めるための解決策を求めています。 – SingerOfTheFall
あなたの問題は、 '3 * pow(10、-14)'が0.000000000000030000000000000000ではなく0.000000000000029999999999999998として表示されているということです。それは二重の精度の限界にかなりあります。 –