Как добиться максимальной точности в сумме расчета ряда? - PullRequest
0 голосов
/ 21 апреля 2019

Я написал код для вычисления суммы ряда 2 ^ (- k), но не знаю, как повысить точность этого вычисления.Это то, что я сделал до сих пор.

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    int i, n;
    float sum = 0;

    cout << "Enter the value of n: ";
    cin >> n;

    for (i=1; i<=n; i++)
        sum += 1.0/pow(2,i);

    cout << "Sum: " << sum;


    return 0;
}

Любые предложения и / или помощь очень ценятся.

Ответы [ 2 ]

0 голосов
/ 21 апреля 2019

Чтобы увидеть более точный вывод, вам нужно запросить больше точности, чем по умолчанию в C ++.Один из способов сделать это:

#include <iomanip>
…
   std::cout << std::setprecision(99);

Далее, рассмотрите этот код:

for (i=1; i<=n; i++)
    sum += 1.0/pow(2,i);

Во-первых, признайте, что качество реализаций pow варьируется.Стандарты C и C ++ слабо оценивают качество операций с плавающей запятой, и некоторые реализации pow возвращают результаты для простых случаев, таких как pow(10, 3), которые немного отличаются от математических результатов.Из-за того, что pow часто применяется, pow(2, i) может не страдать от этой проблемы, но это следует учитывать.

Предположим, pow(2, i) точно вычисляет правильный результат.Предположим также, что ваша реализация C ++ использует общий базовый 32-битный двоичный формат IEEE-754 для float.Если так, то нет ошибки в сумме, вычисленной выше для n ≤ 24.

Это связано с тем, что каждый член 1.0/pow(2, i) представляется в виде одного бита в значении(дробная часть) float, а float имеет 24-битные значения, поэтому 24 последовательных бита могут быть представлены без ошибок.Как только вы увеличите точность, используемую для форматирования вывода, суммы, показанные для n ≤ 24, должны быть точными.

Когда n = 25, сумма больше не помещается в float.В этот момент математический результат будет округлен до ближайшего значения, представляемого в float, обычно используя правило, согласно которому, если есть связь между двумя ближайшими представляемыми значениями, будет выбрано значение с четным младшим битом.Это означает, что результат будет 1, точно.Для всех n> 24 результат будет 1.

. При использовании типа float невозможно повысить точность выше этого.Это связано с тем, что из всех значений, которые могут быть представлены в типе float, 1 - это значение, наиболее близкое к точной математической сумме ряда.Просто нет более близкого представимого значения, поэтому никакие вычисления или изменение исходного кода не могут дать более точного значения.

Вы можете получить более точные значения, используя double вместо float.Если для double используется базовый 64-битный двоичный формат IEEE-754, то это даст точные результаты для n ≤ 53. Для n> 53 результат снова будет равен 1, а сумма может бытьулучшается только при использовании арифметики с расширенной точностью.

Кроме того, обратите внимание, что:

float sum = 0;
for (i=1; i<=n; i++)
    sum += 1.0/pow(2,i);

математически эквивалентно:

float sum = 1 - pow(2.f, (float) -n);
0 голосов
/ 21 апреля 2019

Хм, я думаю, что pow сначала использует base, и показатель степени, подобный этому, также помните -i:

for (i=1; i<=n; i++)
    sum += pow(2,-i);

Вы можете использовать double вместо float при объявлении суммы, чтобы сделать ее еще более точной(double использует больше битов чем float для представления десятичного числа, поэтому он имеет более высокую точность)

...