-2

我刚刚开始使用 C++ 进行编码,但之前对 MATLAB 和 MySql 有相当多的经验。我正在尝试计算一些复合数字,因此准确性是关键。我曾尝试使用双数来做到这一点,但由于某种原因,我只能得到 7 位有效数字的准确度(与浮点数相同)。我什至尝试使用 long double 来尝试计算,但我仍然只能得到 7 sf 的精度。

我没有正确初始化双打吗?我以为它们只是标准库的一部分??非常感谢任何帮助。下面的代码给出了用于计算的代码的主要部分(其余部分主要是加载数据或调试)。


更新

这是代码示例(减去数据读取)。我已经输入了前 5 个值。计算应该给出 ( EXPECTED OUTPUT ) 在 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 第 2 天:-1.09526 第 3 天:5.46038 第 4 天:-1.61801 第 5 天:0.283089

4

2 回答 2

4

double是您机器上的 IEEE 64 位浮点数,因此它存储 15-17 个有效十进制数字。您不必为此做任何特别的事情。您的问题是您将其打印到屏幕上的方式,而您没有显示。默认情况下,这些值四舍五入为 6 位有效数字,因此您应该按如下方式增加它:

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

或者

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

取决于你的输出方法。

更新:使用高精度计算器并手动进行计算,我得到:

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  

这似乎回答了你的问题。

于 2013-01-16T11:31:49.503 回答
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 的因子。

于 2013-01-16T11:30:46.707 回答