Я только начал программировать на C ++, но у меня довольно большой опыт работы с MATLAB и MySql. Я пытаюсь вычислить некоторые составные числа, поэтому точность является ключевой. Я пытался сделать это, используя двойные числа, но по какой-то причине я получаю точность только в 7 значащих цифр (то же самое, что и число с плавающей точкой). Я даже пытался использовать длинный дубль, чтобы попробовать вычисления, но я все еще получаю только 7 с.ф. точности.
Правильно ли я инициализировал дубли? Я думал, что они были только частью стандартной библиотеки ?? Любая помощь с благодарностью. Приведенный ниже код дает основные части кода, используемого для расчета (остальное в основном загрузка данных или отладка).
ОБНОВИТЬ
Вот пример кода (без чтения данных). Я ввел первые 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)))
Ежедневные цены:
1-й день: 0
2-й день: -1,09526
3-й день: 5.46038
4-й день: -1,61801
5-й день: 0,283089
В 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.
double
это IEEE 64-bit float на вашей машине, поэтому он хранит 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
который, кажется, отвечает на ваш вопрос.