0

だから私は次のコードを持っています

int main(){

double d;
cin>>d;

while(d!=0.00)
{
    cout<<d<<endl;
    double m = 100*d;
    int n = m;
    cout<<n<<endl;
    cin>>d;
}

return 0;}

d に 20.40 を入力すると、n の値は 2040 ではなく 2039 になります。置き換えint n = m てみましたint n = (int) mが、結果は同じでした。これを修正する方法はありますか。前もって感謝します。

4

5 に答える 5

3

コードは m を切り捨てますが、丸めが必要です。を含めcmathて使用しますint n = round(m)

于 2013-08-21T15:20:15.773 に答える
2

一般に、10 進数値は、 のような 2 進浮動小数点を使用して正確に表現することはできませんdouble。したがって、値20.40は、元の値を復元するために使用できる近似値として表されます ( 20.4; 精度は保持できません)。たとえば、値をフォーマットする場合などです。これらの近似値で計算を行うと、通常、誤差が増幅されます。

コメントの 1 つで既に述べたように、関連する参考文献は論文「すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと」です。問題を回避する 1 つの潜在的な方法は、10 進浮動小数点を使用することですが、これはまだC++ 標準の一部ではありません。

于 2013-08-21T15:24:44.590 に答える
1

単精度および倍精度の浮動小数点数は整数と同じ方法で格納されないため、整数 (5、10 など) は実際には長い 10 進数 (4.9999001、10.000000001 など) のように見える場合があります。にキャストするとint、整数が切り捨てられるだけです。そのため、数値が現在 として表されている場合、4.999999999それを にキャストするintと が得られます4std::roundほとんどの場合、より良い結果が得られます (数値が 4.6 で、整数部分だけが必要な場合、round はうまく機能しません)。doubleより大きな問題は、 aを anにキャストすることで何を達成したいのintかということです。

一般に、浮動小数点数を扱う場合、最小有効桁数であるイプシロン値を使用する必要があります。したがって、4.9999999 を 5 と比較したい場合は、(疑似コード): を実行しますif abs(5 - 4.9999999) < epsilon, return 5

int main()
{
    double d;
    std::cin >> d;

    while (std::fabs(d - 0.0) > DBL_EPSILON)
    {
        std::cout << d << std::endl;
        double m = 100 * d;
        int n = static_cast<int>(m);
        if (std::fabs(static_cast<double>(n) - m) > DBL_EPSILON)
        {
            n++;
        }
        std::cout << n << std::endl;
        std::cin >> d;
    }

    return 0;
}
于 2013-08-21T15:24:48.117 に答える
0

double を int にキャストすると値が切り捨てられるため、20.40 はおそらく 20.399999 * 100 は 2039.99 です。

int n = round(m);
于 2013-08-21T15:25:59.023 に答える