簡體   English   中英

如何解決C ++中浮點運算的舍入問題?

[英]How to get around rounding issues in floating point arithmetic in C++?

我遇到一些浮點運算不准確的問題。 我正在嘗試根據加權公式計算得分,其中每個輸入變量的重量大約是下一個重要值的20倍。 然而輸入是實數,所以我最終使用double來存儲結果。 下面的代碼存在丟失E1和E2之間差異的問題。

此代碼對性能敏感,因此我需要找到解決此問題的有效方法。 我想把我的輸入乘以一百然后再使用一個int(因為我認為這個就足夠精確了),但我懷疑這是最好的解決方案,因此問題。

#include <iostream>

int main()
{
    double score1, score2;
    float a  = 2.75 ;
    float b  = 5.25 ;
    float c  = 5.25 ;
    float d  = 2.75 ;
    float E1 = 3    ;
    float E2 = 6    ;

    score1 = 20 * b - 1 * a + 0.05 * d  /* - 0.0025 * c*/ + 0.0001 * E1 ;
    score2 = 20 * b - 1 * a + 0.05 * d  /* - 0.0025 * c*/ + 0.0001 * E2 ;

    std::cout << score1 << std::endl;
    std::cout << score2 << std::endl;

    std::cin.get();
    return 0;
}

//ouputs:
//102.388
//102.388
  1. 你沒有輸出整個值,使用cout << setprecision(number_of_digits) << score1 << endl;
  2. 你的分數計算中需要多少個有效數字?

我想把我的輸入乘以一百然后再使用一個int(因為我覺得這樣就足夠精確了),但我懷疑這是最好的解決方案

考慮到你所展示的價值,我會說是。

http://ideone.com/qqTB3向您顯示差異並未丟失,但實際上與您期望的一樣大(達到浮點精度,即雙精度為15位十進制數)。

讓我們看看這段代碼中發生了什么:

score1 = 20 * b - 1 * a + 0.05 * d  /* - 0.0025 * c*/ + 0.0001 * E1 ;

// Multiplication division happens first:

float  tmp1 = static_cast<float>(20) * b;      // 20 cast to float.
float  tmp2 = static_cast<float>(1)  * a;      // 1  cast to float.
double tmp3 = 0.05   * static_cast<double>(d); // d converted to double as 0.05 is double
double tmp4 = 0.0001 * static_cast<double>(E1);// E1 cast to double as 0.0001 is double

// Addition and subtraction now happen
float  tmp5  = tmp1 - tmp2;
double tmp6  = static_cast<double>(tmp5) + tmp3; // tmp5 cast to double as tmp3 is a double.
double tmp7  = tmp6 + tmp4;
score1       = tmp7;

如果我們在腦海中這樣做:

tmp1 = 105.0
tmp2 =   2.75
tmp3 =   0.1375
tmp4 =   0.0003
tmp5 = 107.75
tmp6 = 107.8875
tmp7 = 107.8878

精度應該適用於這些值:
但是當你打印出來時,雙精度的默認精度是3位小數。

std::cout << 107.8878;
> 107.888

所以設置精度:

std::cout << std::setprecision(15) << 107.8878 << "\n";
> 107.8878

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM