Visual Express 2010 с двойной переменной точностью

Я только начал программировать на 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

-2

Решение

В 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.

1

Другие решения

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

который, кажется, отвечает на ваш вопрос.

4

По вопросам рекламы [email protected]