2012-06-16 76 views
6

任何人都可以幫我理解爲什麼x2打印爲零。 我猜是因爲浮點數的表示X1被四捨五入,是否有辦法保持歲差。劃分和浮點數

long double x1, x2; 
x1= 0.087912088; // Note: 360/4095 = 0.087912088 
x2 = 360/4095; 
printf("%Lf, %Lf \n",x1, x2); 

結果:

x1 =0.087912 
x2= 0.000000 
+0

克里斯和列文感謝您的答覆。有沒有辦法增加歲差? – katta

+0

要實際存儲更多數字,您需要一個任意精度庫。只要顯示更多可以像Levon說的那樣完成,或者在C++中用'std :: setprecision'完成。 – chris

+0

@chris我正在研究QNX嵌入式系統上的低級電機控制代碼C。我會牢記C++代碼。 – katta

回答

10

問題是整數截斷 ..你正在分裂兩個整數=>的結果將是丟棄的小數部分的另一個整數。 (例如,在整數除法的實際結果爲3.9時,截斷將使其爲3(即它不輪))。

在你的情況下,如果將其更改爲:

x2 = 360/4095.0; /* one of the operands now has a decimal point */ 

你會得到

0.087912, 0.087912 

作爲輸出。

即,只要一個或除法運算符/的操作數的兩個是浮動/雙打中,結果將是太(即,它會被「提升」到浮動/雙)。所以,我可以改變了x2

x2 = 360.0/4095.0; 

x2 = 360.0/4095; 

,並會得到與上面相同的結果。

正如@chris所提到的,只需使用.就足夠了。

回覆您的問題有關精度上面:

您已經長一倍的工作。我不認爲在內部,除非你使用一些特殊的圖書館,你可以改變什麼,但你肯定可以顯示更多的數字。例如,

printf("%Lf, %.20Lf \n",x1, x2); 

將產生

0.087912, 0.08791208791208791895 

最後,@ EDA-QA莫爾 - ORA-Y提醒我們,你也可以值某些類型的,但它的問題你做吧。一個簡單的例子(注意該值最終成爲float後在任何情況下的分配因爲vfloat):

float v = 0; 
        /* values shown are BEFORE assignment */ 
v = (5/2);   /* value is 2 due to integer truncation before assignment */ 
v = (float) (5/2); /* 2.0 as integer division occurs 1st, then cast to float */ 
v = (float) 5/2; /* 2.5 since 5 becomes 5.0 through casting first. */ 
+0

只是在最後一個點就足夠了爲好。 – chris

+0

@chris謝謝..我沒有意識到..學到了一些新的東西:)我會添加到答案。 – Levon

+0

我都學到新的東西too..Thanks傢伙 – katta

3

內置運營商在同一類型的對象的工作。結果與參數類型相同。在這種情況下,除法是在兩個整數上完成的,因此結果是一個整數。

x2 = 360/4096; 
// int/int = int 

因此,我期望的結果爲0。

如果在內置型運營商不同的人會提倡,使它們具有相同的類型(和結果也是該類型)。所以你想要的是:

x2 = 1.0 * 360/4095; // or 360.0/4095 

// This is 
    double * int/int 

==> (double * double)/int 
==> (double * double)/double