2017-02-28 99 views
5

我的程序中有一個奇怪的行爲,其中雙精度失去了精度。我的cout的顯示正確的值,但仍然是行爲意外。因此我調試和發現甚至gdb顯示意外的值。 以下僅是簡化方案:gdb顯示不正確的double值

double length =2.11; 
//gdb shows 2.10 here but prints 2.11 correctly using cout at the end 
cout<<"length; //It prints 2.11 correctly here 

通常,這樣的問題是很難找到生產場景中調試是不是一種選擇,唯一的選擇是使用盡可能多的打印成爲可能。 任何建議如何避免這個問題?

+1

錯誤的問題(因爲你忘了激勵它,實際上有一些[XY問題](http://xyproblem.info)...)。正如你所評論的那樣,你不會操縱*數字*,而是一些巴洛克長度表示(因爲你評論說'2.11'意思是2英尺和11英寸) –

+1

如果你使用'double',一定要花幾個小時才能讀取http: //floating-point-gui.de/ –

+0

@BasileStarynkevitch:絕對好的建議。掌握了這些知識後,你們也會在派對上喋喋不休。 – Bathsheba

回答

6

假設IEEE754雙精度浮點,最接近double至2.11是稍小

2.109999999999999875655021241982467472553253173828125

std::cout是足夠聰明的默認適當圓形,但GDB似乎截斷至2個小數位。

+0

我該如何避免這種情況?假設我有一個雙變量作爲'double var = 2.11',其中2代表feets和11英寸,我如何從中提取0.11部分,因爲它總是使它成爲10而不是11 – anurag86

+3

這是一個有問題的使用'double'而不是微不足道的解決。爲什麼不單獨使用'struct'建模'feet'和'inches'?你甚至可以在它上面建立一個「標準化」方法,將1英尺13英寸轉換爲2英尺1英寸。 – Bathsheba

+2

有這樣的表示是一個巨大的錯誤。 'double' *近似* [實數](https://en.wikipedia.org/wiki/Real_number)。你的數據甚至不是一個數字。或者(並且優選地)*將它轉換爲某種長度(例如,在*米*)或保留其他東西(一個'std :: string',一個'std :: pair ') –

2

鑑於實際數據的行爲與您的情況一樣,我擔心沒有太多要做。您可以計劃避免它,並創建空間來對您的double值執行平等檢查。

這裏有你們兩個似是而非的黑客:

1:在一所大學的項目嘗試這樣做]與數字打交道的順序10^-4,用一個整數和一個因子值。例如:存儲1.2345,存儲整數12345和因子10000.現在您可以正確打印,這也可以進行平等檢查。 2:如果已知雙精度值的準確性,則可以使用偏移量。例如:如果2.109999具有2位小數的精度,請使用如下所示: (int)((2.109999 + .005)* 100)。然後相應地打印。

但是這兩個黑客假定以下:

1:你對值的精確控制。 2:你真的需要打印準確的值。