0

シンプルなメインに次のソースコードがあります。

int main(int argc, char** argv)
{
    double x = atof(argv[1]);
    double y = atof(argv[2]);

    double res = x + std::floor((y - x) * .5 * 100 + .5)*0.01;

    std::cout << res << std::endl;
}

上記を75.2175.22で実行すると、75.22になりますが、7.21と7.22で実行すると、7.21になります。これらの数値は両方とも0.01異なるので、なぜこれが起こっているのかわかりませんか?

4

4 に答える 4

5

簡単な答え:浮動小数点値は不正確です。

長い答え:すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

于 2013-01-18T22:08:42.260 に答える
3

浮動小数点演算の多くの複雑さの中には、浮動小数点数が最小値と最大値の間の実数直線に沿って均等に分散されていないという事実があります。0実数直線上の点と見なされる浮動小数点数に近いものは、から離れるよりも密度が高く、から0の(絶対)距離が0増加するにつれて密度は減少します。

通常のIEEE標準表現の場合、たとえば1(base-10)と2(base-10)の間には、2(base-10)と4(base-10)の間と同じ数の数値があります。区間の両方の端点が表現可能であるように[2^i,2^i+1]、任意の(正または負の)整数の区間には同じ数の浮動小数点数があります。i

これを考慮すると、関係する絶対値の大きさが増加するにつれて、10進数の計算の精度が低下することは驚くべきことではありません。

于 2013-01-18T22:12:17.023 に答える
0

in x = atof ()正しくないことはできません

double atof ( const char * str )
于 2013-01-18T22:10:35.850 に答える
0

2つのほぼ同じ数yとを減算xして、両方よりも桁違いに小さい数を取得すると、常に多くの精度が失われます(ただし、両方の2進展開が、53ビット目までに終了するというまれなケースを除きます)yxそれは驚くべきことではありません。

この特定のケースでは、計算するだけで、トリックなしで「問題」を簡単に確認できます。

75.22 - 75.21

7.22 - 7.21

(結果はそれぞれ0.01000000000000510.00999999999999979になります)。

于 2013-01-19T18:56:30.403 に答える