簡體   English   中英

C ++使用stringstream進行雙轉換的字符串會產生精度錯誤

[英]C++ String to double conversion using stringstream gives precision error

這是我的代碼片段。 我需要一些幫助來消除下面顯示的錯誤。

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    char doubleStr[] = "5.2";
    double d = 0.0;
    std::stringstream stream (doubleStr);
    stream >> d;
    std::cout << d << std::endl;
    std::cout << (d <= 5.2);
    return 0;
}

這給出了輸出:

5.200000000002
0

如何清除此精度錯誤? 我可以使用std :: setprecision()來解決問題嗎?

numeric_limits<double>::digits10可用於查找double可唯一表示的位數。

我看到你用Visual Studio標記了你的問題。 您可以在http://webcompiler.cloudapp.net/上測試此代碼,以獲取Visual Studio的double精度可唯一表示的數字:

#include <iostream>
#include <limits>

int main() { std::cout << std::numeric_limits<double>::digits10 << std::endl; }

此代碼將輸出2它將輸出:

15

這意味着任何double到14位小數的double 在通過stringstream流的往返中存活並仍然等於它自己。


以上意味着您的示例中沒有包含導致往返失敗的內容,或者您​​使用的是非IEEE標准的非標准源文件。 (例如,我可以在gcc上做一個實例 ,給你的相反輸出,在Visual Studio上運行相同的代碼不同意你的輸出。)

無論哪種方式,對於任何唯一可表示的double精度(如5.2),您可以通過設置精度來確保通過stringstream流的往返成功。 Precision是一個粘性修改器,所以你只需要在流構造之后設置一次。 在您的例子中,你使用stringstream stream ,所以你一起工作之前stream ,你就需要設置這個修改:

stream.precision(numeric_limits<double>::digits10 - 1);

您可以像這樣使用它,以便以正確的方式顯示雙號:

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <limits>
int main()
{
    char doubleStr[] = "5.2";
    double d = 0.0;
    std::stringstream stream (doubleStr);
    stream >> d;
    std::cout << std::setprecision(2)<<  d << std::endl;
    return 0;
}

http://cpp.sh/9lub

關於比較浮點數你可以看一下浮點數和雙重比較最有效的方法是什么?

暫無
暫無

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

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