2

課題用に以下のプログラムを作成しました。元本、最低利率、最高利率、利息を積み立てる年数を入力できるはずです。

テスト後、最高利率を .06、.6 などと入力しない限り、すべて問題なく動作します。何らかの理由で、最高利率が表示されません。最低利率として .06 を入力すると正常に表示され、.06 よりも高い最高利率を使用すると、.06 の金額が表示されます。私に問題を提示する他の量はありません。

これを修正するために何を変更する必要があるかを理解するのを手伝ってくれる人はいますか?

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

int main()
{
    //variables & named constants
    int principal = 0;
    double minimumInterest = 0.0;
    double maximumInterest = 0.0;
    int yearBase = 1;
    int years = 0;
    double balance = 0.0;

    //inputs
    cout << "Enter the beginning principal: $";
    cin >> principal;

    cout << "Enter the minimum interest rate: ";
    cin >> minimumInterest;

    cout << "Enter the maximum interest rate: ";
    cin >> maximumInterest;

    cout << "Enter the number of years the interest will accumlate: ";
    cin >> years;

    //calculations & loop
    do
    {
                  cout << "Year " << yearBase << ":" << endl; 
                  for (double rate = minimumInterest; rate <= maximumInterest; rate += .01)
                  {
                      balance = principal * pow(1 + rate, yearBase);

                      //display rate with zero decimal places
                      cout << fixed << setprecision(0);
                      cout << "     Rate " << rate * 100 << "%: $";

                      //display balance with two decimal places
                      cout << setprecision(2) << balance << endl;
                  }

                      //update years counter
                      yearBase +=1;       
    } while (yearBase <= years);
    system("pause");
    return 0;                   
}  
4

2 に答える 2

1

浮動小数点の不正確さについての答えは正しく、お金を話すときに浮動小数点数を使用しない理由です。

少しの変更で作業できるようにする簡単なハックは、次のように変更することです。

for (double rate = minimumInterest; rate <= maximumInterest; rate += .01)

に:

for (double rate = minimumInterest; rate <= (maximumInterest+0.001); rate += .01)

そしてそれはうまくいくでしょう。とにかくあなたのお金の計算はある時点で間違っているでしょう。

正しい実装では、固定小数点演算を使用します。

于 2012-10-27T01:27:01.690 に答える
1

double10 進値を正確に表すわけではありません: これは 2 進浮動小数点です。つまり、その内部表現は _(-1)符号*有意* 2指数で、符号は 0 または 1、有意は符号なし整数、指数は符号付きです。整数。これは、0.01 や 0.6 などを正確に表現できないことを示す比較的単純な引数です。つまり、0.01 を 60 回加算する計算は、おそらく 0.6 ではありません。実際、これらの値を十分な桁数で出力すると、その効果を確認できます。

#include <iostream>
#include <iomanip>
#include <limits>

int main()
{
    double sum;
    double small(0.01);
    double big(0.6);

    for (int i(0); i != 60; ++i) {
        sum += small;
    }

    std::cout << std::setprecision(std::numeric_limits<double>::digits10 + 4)
              << "small=" << small << "\n"
              << "big=" << big << "\n"
              << "sum=" << sum << "\n";
} 

このプログラムを実行すると、次のような結果が得られます。

small=0.01000000000000000021
big=0.5999999999999999778
sum=0.6000000000000003109

計算で使用された正確な値を確認したい場合は、精度を に設定する必要がありますstd::numeric_limits<double>::digits。しかし、それはきれいに見えません。

さて、このような問題にどのように対処するかという興味深い質問はありますか? 10 進数で計算する場合の一般的な解決策は、10 進浮動小数点を使用することですが、C++ 標準ライブラリに追加することが提案されている段階にすぎません。金利を正確に維持することができます。特定のセットアップの場合、おそらく最も簡単な方法は、利率を使用してループの実行を制御するのではなく、適切なカウンターを使用することです。

于 2012-10-27T01:17:16.170 に答える