Формула Лейбница для π / 4
Меня просят вывести суммирование формулы Лейбница до n-го члена ряда с точностью до 15 десятичных знаков. places.In исчисление, формула Лейбница для π задается:
1 - 1/3 + 1/5 -1/7 + ... = π/4
Это мой код
#include<stdio.h>
#include<math.h>
int main()
{
int n,i;
long double s=0;
scanf("%d",&n);
for(i=0;i<n;i++){
s+=(long double)pow(-1,i)/(2*i+1);
}
printf("%Lfn",s);
return 0;
}
Может ли кто-нибудь сказать мне, почему я не могу достичь точности до 15-го десятичного знака?
Моя цель не состоит в том, чтобы вывести значение pi / 4, я просто должен вывести суммирование для данного n
2 ответов:
Вопрос: почему ... достичь точности до 15-го десятичного знака?
A: для отображения 15 десятичных знаков после десятичной точки используйте формат"%0.15f". Чтобы вычислить 15 десятичных знаков сходимости, как минимум,nдолжен быть очень большим.Как упоминалось @user3386109, " ошибка в результате ограничена 1 / (2n+1)", поэтому потребуется около 5e14 итераций. (Приблизительная оценка: 10 дней на моем компьютере.) Как типичный
doubleимеет точность около 1 части в pow (2,53) или 1 в 9e15, то достигаются пределы расчетаdouble. Приведенный ниже код сравнивает порядок вычисления, чтобы уменьшить ошибку, но в лучшем случае , ошибка все равно будет составлять не менее 0,5 частей в 9e15.Поскольку члены ряда колеблются около предела, при остановке после
nитераций можно добавить конечную итерацию 1/2 следующей итерации. это позволило бы получить около 1 бита точности.Как уже упоминалось, существуют и другие методы вычисления π, которые сходятся быстрее.
Обновлено в соответствии с хорошим наблюдением @user3386109.
При суммировании терминов код может суммировать их в различных порядках. Приведенные ниже методы 2 иллюстрируют, что скромно более стабильный результат достигается раньше, когда сначала суммируются малые члены вместе. Я ожидал бы в лучшем случае только 1 или 2 бит лучшего ответа.Это было сделано повторно с использованием
float, так как небольшое улучшение не проявляется до тех пор, пока последние несколько битов не станут стабильными. Сdoubleи этот медленно сходящийся ряд, это займет слишком много времени.//Leibniz formula for pi/4 typedef float fp; fp LeibnizForward(unsigned n) { volatile fp sum = 0.0; fp sign = 1.0; unsigned i = 1; while (n-- > 0) { sum += sign / i; sign = -sign; i = (i + 2); } return sum; } fp LeibnizReverse(unsigned n) { volatile fp sum = 0.0; fp sign = 1.0; unsigned i = 2 * n - 1; if (n % 2 == 0) sign = -sign; while (n-- > 0) { sum += sign / i; sign = -sign; i = (i - 2); } return sum; } void PiTest(unsigned n) { printf("%u\n", n); static const fp pic = 3.1415926535897932384626433832795; const char *format = "%s %0.9f\n"; printf(format, "pi-", nextafterf(pic,0)); printf(format, "pi ", pic); printf(format, "pi+", nextafterf(pic,4)); fp pif = LeibnizForward(n) * 4; printf(format, "pif", pif); fflush(stdout); fp pir = LeibnizReverse(n) * 4; printf(format, "pir", pir); fflush(stdout); } int main(void) { PiTest(0); PiTest(1); PiTest(10); PiTest(100); PiTest(1000); PiTest(10000); PiTest(100000); PiTest(1000000); PiTest(10000000); PiTest(100000000); return 0; } 0 pi- 3.141592503 pi 3.141592741 pi+ 3.141592979 pif 0.000000000 pir 0.000000000 1 pi- 3.141592503 pi 3.141592741 pi+ 3.141592979 pif 4.000000000 pir 4.000000000 10 pi- 3.141592503 pi 3.141592741 pi+ 3.141592979 pif 3.041839600 pir 3.041839600 25 pi- 3.141592503 pi 3.141592741 pi+ 3.141592979 pif 3.181576490 pir 3.181576729 100 pi- 3.141592503 pi 3.141592741 pi+ 3.141592979 pif 3.131592512 pir 3.131592751 1000 pi- 3.14 1592503 pi 3.14 1592741 pi+ 3.14 1592979 pif 3.14 0592575 pir 3.14 0592575 10000 pi- 3.141 592503 pi 3.141 592741 pi+ 3.141 592979 pif 3.141 498566 pir 3.141 492605 100000 pi- 3.1415 92503 pi 3.1415 92741 pi+ 3.1415 92979 pif 3.1415 85827 pir 3.1415 82489 1000000 pi- 3.14159 2503 pi 3.14159 2741 pi+ 3.14159 2979 pif 3.14159 5364 pir 3.14159 1549 10000000 pi- 3.14159 2503 previous float pi 3.14159 2741 machine float pi pi+ 3.14159 2979 next float pif 3.14159 6794 pir 3.14159 2503 100000000 Additional iterations do not improve the result. pi- 3.14159 2503 pi 3.14159 2741 pi+ 3.14159 2979 pif 3.14159 6794 pir 3.14159 2503 1000000000 pi- 3.14159 2503 pi 3.14159 2741 pi+ 3.14159 2979 pif 3.14159 6794 pir 3.14159 2503
Измените оператор
printf, чтобы вывести больше значений после десятичной точки.В качестве примера, используя
printf("%30.28Lf\n",s);Выведет число на 28 знаков после запятой. С помощью
n=25я получил следующий результат.0.7953941713587578038252220991
Comments