2017-04-14 44 views
0

分裂雙重我有這三個數字:如何解析和C++

double n1 = 1.1 
double n2 = 1.10 
double n3 = 1.101 

,我希望將它們轉換成字符串到小數部分分離到別的地方使用它們。因此,我想有以下幾點:

string s1 = 1 
string s2 = 10 
string s3 = 101 

我讀這使用std::to_string,因爲它總是返回所有小數,例如是不可能的s3將類似101000

然後我嘗試了以下內容:

double n3 = 1.101; 
std::ostringstream strs; 
strs << n3; 
std::string str = strs.str(); 

boost::char_separator<char> sep("."); 
boost::tokenizer<boost::char_separator<char>> tokens(str,sep); 

for (const auto& t : tokens) { 
    EV << "separated parts " << t << endl; 
} 

這個作品在n1n3情況很好,但是當我使用n2返回1,而不是10

我在想如何解決這個問題,唯一的問題是在轉換爲字符串然後再次設置精度之前計算精度。

這是一個可行的策略嗎? 如何計算點後有多少位數?

+0

'1.1 == 1.10',沒有區別。 – Jarod42

+0

簡單的初等數學,它在小數部分末尾有多少零並不重要。因此,1.1 == 1.10,也1.10 == 1.100000000000000000 ... –

+0

爲什麼不使用['std :: modf()'](http://en.cppreference.com/w/cpp/numeric/math/modf) ? – piwi

回答

2

如果你的號碼最初是在數據類型double出現,那麼,我認爲沒有機會的小數部分寫在用於初始化文字分開。這些信息簡單地丟失,我會嘗試在下面的段落解釋:

注意文字1.101.1都站了數字文本double類型。編譯器會將文字轉換爲浮點表示/二進制表示,並且1.101.1將實現完全相同的二進制表示。因此,您將不會有任何機會確定是否使用字面值1.11.10來初始化雙精度值。

事情變得更糟,當我們考慮到十進制數1.1沒有一個確切的二進制表示,但導致重複分數:

0.1₁₀ = 0.0001100110011001100110011001100110011001100110011…₂ 

所以,當你打印出文字1.1(或1.10,這是相同),這取決於精度上要舍:

std::cout << "1.1 is..." << std::setprecision(6) << 1.1 << std::endl; 
std::cout << "1.1 is..." << std::setprecision(17) << 1.1 << std::endl; 
// 1.1 is...1.1 
// 1.1 is...1.1000000000000001 

這意味着 - 一旦存儲爲雙值,你根據前不同的結果您用於打印價值的cision;這也適用於將小數部分轉換爲字符串,實際上與以特定精度打印相同。

更糟糕的是,由於暫時不能夠以二進制形式精確表示每一個十進制值,兩個不同的十進制值可以以二進制形式產生相同的值:

double n1 = 1.1; 
double n2 = 1.100000000000000088817841970012523233890533447265625; 

if (n1 == n2) 
    std::cout << "equal!" << std::endl; 
// Output: equal! 

所以你不能分辨n1n2以上。

了很多的話,和簡短的結論:

如果你想從1.10區分1.1,或者如果你通常想找出數字文字的小數部分寫在你的源代碼,那麼你必須將它們存儲起來最初爲作爲字符串,而不是雙打。

0

我想你並不熟悉'浮點數'實際是什麼。

double是浮點數,如https://en.wikipedia.org/wiki/IEEE_floating_point所述。基本上1.101.1相同,與1.1000000等同。

現在,有一種稱爲「定點數」的解決方案,通常稱爲「小數」和「數字」。如果您熟悉數據庫引擎,則知道1.10是數字(3,2),1.1是數字(2,1)。注意類型如何改變和定義精度(位數)和縮放比例(逗號後的位數)。但是,C++本身不支持小數。

+0

感謝您的回覆,但我不明白這對我有何幫助。你是說我想做什麼是不可能的? – brid

+0

@brid,'double'不存儲關於有多少數字的信息。所以不,使用簡單的雙倍是不可能的。您當然可以將其包裝在自定義數據結構中,並在解析時添加該信息,或者使用固定點庫。 – atlaste

-2

這只是簡單的數學。 解析器只是轉換你的X.10到X.1 :)