2013-01-16 86 views
-2

我剛剛開始用C++編寫代碼,但在MATLAB和MySql中有相當多的以前的經驗。我正在計算一些複合數字,因此準確性是關鍵。我試圖用雙數來做到這一點,但由於某種原因,我只能得到7位有效數字的準確性(與浮點數相同)。我甚至嘗試使用一個長雙重來嘗試計算,但我仍然只得到7 s.f.的精度。Visual Express 2010 double variable precision

我沒有正確初始化雙打嗎?我以爲他們只是標準庫的一部分?任何幫助不勝感激。下面的代碼給出了用於計算的代碼的主要部分(其餘部分主要是加載數據或調試)。


UPDATE

下面是代碼(減去數據讀取)的一個樣本。我輸入了前5個值。計算應該給(預期輸出)在Excel計算,使用完全相同的輸入:

0 
-1.09526 
4.364551963 
2.745835774 
3.029002506 

什麼下面的代碼給出(實際輸出):

0 
-1.095260000 
4.3591394642 
2.7340763329 
3.0179393198 

代碼:

#include <fstream> 
#include <iostream> 
#include <sstream> 
#include <string> 
#include <vector> 


using namespace std; 

int main(){ 

std::vector<double> compoundedcalculation; // pre-allocating for the compounded calculations 
std::vector<double> dailycompound; // pre-allocating for daily compoundvalue 
compoundedcalculation.insert(compoundedcalculation.end(), 0.0); // setting the first value as 0 

double dailycompoundval[] = {0,-1.09526,5.46038,-1.61801,0.283089}; 
dailycompound.assign(dailycompoundval,dailycompoundval+5); 
double indCC; 

for (int n = 0; n < 5 ;n++) 
    { 
    indCC = ((((1+((compoundedcalculation.at(n))/1000))*(1+((dailycompound.at(n))/1000)))-1)*1000); 

    printf(" %.17g \n", indCC); 


    compoundedcalculation.insert(compoundedcalculation.end(), indCC); 
    } 
return 0; 
} 

感謝您的努力。


更新2:

預期和實效使用相同的公式爲複合。

混配總=((1+(每日房價/ 10000))*(1+(前復配合計/ 10000)))

每日房價:

第一天:0 第二天:-1.09526 第3天:5.46038 第4天:-1.61801 第5天:0.283089

+1

你怎麼知道它只存儲7位數的精度? – yiding

+0

您應該在打印數字的位置包含該部分,還是隻在調試器中查找? – Mario

+0

這是毫無意義的要求我們猜測。如果你想得到有意義的幫助,你應該展示一個展現你不明白的行爲的程序。然後我們可以解釋它。 –

回答

1

在Visual Studio中,double是IEEE754雙精密度。它具有53位的二進制精度,或約15-16位有效數字。

可能只是打印值的診斷代碼打印到7位數的精度。或者你的調試器視圖只顯示7位精度。

換句話說,問題不在於底層數據類型,而在於您查看數據的方式。

更新1

您的評論表明您認爲雙精度值計算正在開展爲單精度。默認情況下不會如此。如果您通過調用_controlfp來更改浮點精度控制,可能會發生這種情況。但是,如果將浮點控件設置爲默認值,則對雙精度值的操作將不會舍入爲單精度。

更新2次

您的Excel計算,執行不同的計算。 C++程序的輸出與代碼匹配。與代碼匹配的第一個非零值輸出-1.09526。因爲代碼說的值應該是dailycompoundval[1]。 Excel代碼中的相應值爲-1.095231419,因此它與C++代碼不匹配。

換句話說,問題是一個紅鯡魚。這裏沒有舍入問題。問題完全取決於代碼的兩個不同版本之間的差異。

更新3

你的C++代碼不匹配最新的更新的表達。代碼使用乘法因子1000,但是您的表達式使用的因子爲10000.

+0

感謝您的回答,但精度誤差在實際計算中,而不是顯示/結果。 – Mkoll

+0

@Mkoll如果是這樣,請證明。製作一個表明這一點的程序。直到你能這樣做,我們才能做的事情並不多。 –

+0

已編輯原始帖子以包含一個小程序以產生錯誤。歡呼聲 – Mkoll

4

double是IEEE 64位浮點數,因此它存儲15-17個重要的十進制數字。你不必爲此做任何特別的事情。你的問題是你打印到屏幕上的方式,你沒有看到。默認情況下,該值被四捨五入到6個顯著數字,所以你應該增加它,如下所示:根據您的輸出方法

cout.precision(17); 
cout << x; 

printf("%.17g", x); 

UPDATE:以高精度計算器和手工做的計算,我得到:

n = 0: ((1 + 0/1000)*(1 + 0/1000) - 1)*1000 
     == 0 
n = 1: ((1 + 0/1000)*(1 + -1.09526/1000) - 1)*1000 
     == -1.09526 
n = 2: ((1 + -1.09526/1000)*(1 + 5.46038/1000) - 1)*1000 
     == 4.3591394642012 
n = 3: ((1 + 4.3591394642012/1000)*(1 + -1.61801/1000) - 1)*1000 
     == 2.734076332956727816388 
n = 4: ((1 + 2.734076332956727816388/1000)*(1 + 0.283089/1000) - 1)*1000 
     == 3.017939319891748203508813462532 

我得到相同的結果,當我運行代碼:

0 
-1.0952599999999999 
4.3591394642012 
2.7340763329567279 
3.0179393198917484 

然而,當我取代1000×10000我得到你的「預期結果」,

0 
-1.0952599999999999 
4.3645219464201199 
2.7458057624046663 
3.0289724931454134 

這似乎回答你的問題。

+0

感謝您的答案,但精度誤差是在實際計算,而不是顯示/結果。 – Mkoll

+0

@Mkoll:如果您嘗試了上述內容,請發佈您期望的輸出和輸出。最好發佈[SSCCE](http://sscce.org/)。 – ybungalobill

+0

嘿ybungalobill,已經添加了一個結果的例子和一個小問題的程序。謝謝! – Mkoll