Пи в квадрате до n цифр С++

Я нашел много похожих тем, но ни одна из них не дает мне четкого объяснения.

Мне нужно написать программу, которая вычисляет число Пи в n цифрах, используя этот ряд Тейлора:

π^2 = 12 ( 1/1^2 - 1/2^2 + 1/3^2 - 1/4^2 + ... )

Я написал это:

#include <iostream>
#include <math.h>

using namespace std;

int main() {
    int n;
    cout << "How many digits?" << endl;
    cin >> n;
    long double Pi2 = 0;
    int i = 1;

    while( precision is less than n ) {
        if ((i%2) == 1) { 
            Pi2 += 1/pow(i,2); 
            i+=1;
    }
        else {
            Pi2 -= 1/pow(i,2); 
            i+=1; 
            }
    }

Pi2 *= 12;

cout << Pi2 << endl;
return 0;
}

и я понятия не имею, что писать в while() ? Когда этот цикл должен остановиться?


person maja    schedule 15.03.2014    source источник
comment
Когда вы хотите, чтобы он остановился (т.е. когда вы вычислили число пи до n цифр)   -  person OMGtechy    schedule 15.03.2014
comment
Это математическая задача, а не программная. Ошибка — оставшиеся бесконечные элементы, которые вы не вычисляете. Вы можете получить привязку к этой сумме, и тогда вы знаете, когда остановиться   -  person odedsh    schedule 15.03.2014
comment
Вот некоторые материалы для чтения без решения домашнего задания: zweigmedia.com/pdfs/TaylorSeries.pdf.. и, кстати, вопросы такого типа принадлежат math.stackexchange.com/‎   -  person odedsh    schedule 15.03.2014
comment
См. этот код stackoverflow.com/questions/22050980/ и запишите время в эпсилон.   -  person Ed Heal    schedule 15.03.2014


Ответы (2)


Если вы знаете требуемую точность, вы можете вычислить правильное значение максимального значения для n до того, как начнете цикл. Второе: начните с наименьшего числа, если вы начинаете складывать все значения дельты.

Подобно этому

int ndigits;
cout << "How many digits?" << endl;
cin >> ndigits;
int n = int( pow( double(10), double(ndigits)/2 ) + 0.5 );
long double Pi2 = 0;
int i = 1;

for( int i=n; i>0; --i ) 
{
    if ((i%2) == 1) { 
        Pi2 += 1/pow(long double(i),2); 
    }
    else {
        Pi2 -= 1/pow(long double(i),2); 
    }
}
Pi2 *= 12;
person cpp-progger    schedule 15.03.2014
comment
Спасибо, это работает, но не могли бы вы объяснить, почему 10^ndig/2+0,5 ? Я знаю, что это математическая проблема... но если бы вы могли объяснить это как-то просто, я был бы признателен :) - person maja; 17.03.2014
comment
хорошо, кажется, я это уже знаю, но у меня есть еще один вопрос ;) Не могли бы вы объяснить, почему эта программа должна начинаться с конца - я имею в виду --i? это что-то удивительное для меня. Если можно начать с начала, я имею в виду итерации, начиная с i=1, как будет выглядеть эта программа? Я попытался изменить его на (int i=1; i‹n; i++), и он дает немного другие вычисления. Почему? Извините за глупые вопросы, но у меня было всего 3 класса c++ ;) - person maja; 17.03.2014
comment
если вы начинаете с i = 0, ваше первое значение равно 0,5. Сумма Pi2 возрастает до 0,8 и более. При больших значениях i смещение, которое будет добавлено, становится очень маленьким, например. 0,00000001.. Точность двойного или длинного двойного числа ограничена, поэтому при добавлении двух чисел очень разного масштаба меньшее из них потеряет точность. Сделай один раз не проблема - много 10000 раз теряешь точность в сумме. Изменение порядка чисел означает, что оба числа имеют одинаковый масштаб и не теряют точности. - person cpp-progger; 17.03.2014

Метод, который следует рассмотреть, – это использование ndigits для создания значения "эпсилон".
Предположим, что ndigits равно 3. Это дает эпсилон 0,0001.

если разница между вашим значением из предыдущей итерации и текущей итерацией меньше 0,0001, вы можете предположить, что у вас есть значение, которое вам нужно, и завершить цикл while.

Предупреждение однако. У двойников и длинных двойников есть верхний предел количества цифр, которые они могут точно хранить.

person EvilTeach    schedule 15.03.2014
comment
Как я могу проверить, меньше ли разница между значением из предыдущей итерации и текущей? извините, я знаю, что это просто, но я пытаюсь и получаю ошибки. - person maja; 16.03.2014