2012-04-26 644 views
5

在UNIX中使用sprintf()double值轉換爲字符串時,我遇到了一個特定問題。double值的sprintf格式化

比如我有兩個值:

double a = 0.009984354523452; 
double b = 0.01; 

雖然轉換,我使用:

sprintf(somestringvar, "Double value : %.15f \n", a); 
sprintf(diffstringvar, "Double value : %.15f \n", b); 

轉換爲字符串。

我的問題是'a',值正確打印,但'b'的值,0的尾部追加。請給我提供任何常用的方法來表示'a'和'b'爲準確的值。

+1

我會使用std :: ostringstream這種事情。 – Robinson 2012-04-26 06:21:12

+1

一般來說,不要使用'sprintf()',因爲它會導致緩衝區溢出。改爲使用'snprintf()',或者Microsoft在Windows上提供的'_s'「安全」版本之一。附:歡迎來到堆棧溢出! – 2012-04-26 06:21:41

+0

嗨,感謝您的早期迴應。 ostringstream不是完全精確的。值僅打印爲0.009976。我可以使用snprintf(),但問題是在正確打印值時。 – sandy 2012-04-26 07:01:24

回答

8

打印b時會得到零,因爲您告訴printf打印15個小數位(%.15f),並且它正在乖乖地這樣做。爲了獲得「確切」的東西,你可能會用簡單的%g獲得更好的運氣。


[基於最近的評論更新]

事情真的取決於你所說的「精確」的東西。如果確切地說,你的意思是「用戶最初輸入的內容」,那麼雙倍可能不是你的最佳選擇。也許將值存儲爲字符串,然後在需要在計算中使用它時將其轉換爲double可能會有效。一旦基於文本的十進制數字轉換爲雙精度數字,它通常不再與文本完全相同。雖然printf()ostream將忠實地打印雙精度值(有時它很幸運,它打印的內容看起來與原始值相同),但問題在於雙精度本身不再保持實際的原始值。事實上它從來沒有。

或者,您可能更喜歡精確的數字實現,而不是像雙打那樣天生就近似的東西。例如,MySQL有NUMERIC and DECIMAL類型支持完美的精度,代價是強制您提前指定整數和小數位數。這叫做arbitrary precision arithmetic,在C/C++中有這樣做的庫。

+0

感謝您的回覆,我可以理解添加zeoes的邏輯部分。但問題是在運行時我應該從數據庫讀取值。值可以是任何類型,如上所示,所以我正在尋找打印精確值的一般方法。我嘗試了'%g',即使它將值'a'歸一化爲0.009976 – sandy 2012-04-26 07:05:28

+0

爲什麼人們會一直投票呢?如果出現問題,請大聲說出來,以便我可以改進它,或者提供您自己的替代答案。 – 2013-09-16 00:41:23