2013-01-16 56 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