Как вычислить число пи c
Самый простой и легкий в реализации метод.
Рассмотрим произвольный квадрат с центром в начале координат и вписанный в него круг. Будем рассматривать только первую координатную четверть. В ней будет находиться четверть круга и четверть квадрата. Обозначим радиус круга r, тогда четверть квадрата тоже будет квадратом(очевидно) со стороной r.
Будем случайным образом выбирать точки в этом квадрате и считать количество точек, попавших в четверть круга. Благодаря теории вероятности мы знаем, что отношение попаданий в четверть круга к попаданиям ‘в молоко’ равно отношению площадей — пи/4. Вот, собственно, и весь алгоритм. Чем больше взятых наугад точек мы проверим, тем точнее будет отношение площадей.
Вот простенькая программа на Паскале, считающая пи этим способом. Четыре первых знака требуют на моем PentiumII-300 около 5 минут.
uses Crt; const n=10000000; r=46340; r2=46340*46340; var i,pass : LongInt; x,y : real; begin WriteLn('Поехали!'); Randomize; pass:=0; for i:=1 to n do begin x:=Random(r+1); y:=Random(r+1); if ( x*x+y*y < r2 ) then INC(pass); end; TextColor(GREEN); WriteLn('Число ПИ получилось равным: ',(pass/i*4):0:5); ReadLn; end.
Однако, как говорил Козьма Прутков, 'нельзя объять необъятное', что, в применении к данному случаю, можно перефразировать так: нельзя просуммировать бесконечное число слагаемых за конечное время, каким бы быстрым компьютером мы не располагали.
Слава Богу, этого и не требуется. Поскольку мы хотим найти не точное значение PI, а лишь его приближение с пятью верными десятичными знаками, нам достаточно просуммировать такое количество первых членов ряда, чтобы сумма всех оставшихся членов не превышала 10 -5 .
Остался, правда, открытым вопрос о том, сколько же все-таки членов ряда нужно просуммировать, чтобы получить результат с требуемой точностью?
Ответ на этот вопрос в 'общем виде' выходит далеко за рамки настоящего обсуждения. Это отдельная тема в курсах математического анализа и численных методов.
К счастью, данный конкретный ряд позволяет найти очень простое правило, позволяющее определить момент, когда следует прекратить суммирование. Дело в том, что ряд Грегори является знакопеременным и сходится равномерно (хотя и медленнее, чем хотелось бы). Это означает, что для любого нечетного n , сумма первых n членов ряда всегда дает верхнюю оценку для PI, а сумма n +1 первых членов ряда - нижнюю.
Значит, как только разница между верхней и нижней оценками окажется меньше, чем требуемая точность, можно смело прекращать вычисления и быть уверенным, что как та, так и другая оценки отличаются от истинного значения PI не более, чем на 10 -5 . В качестве окончательного результата разумно взять среднее значение между полученными верхней и нижней оценками. Таким образом, можно предложить алгоритм, приведенный ниже.
Положить n=0, S1 = 0 и S2 = 0; ( начальные установки ) Увеличить n на 1; ( n становится нечетным ) Вычислить S1 = S2 + 4/(2n-1); (S1 - есть верхняя оценка ) Увеличить n на 1; ( n становится четным ) Вычислить S2 = S1 - 4/(2n-1); (S2 - есть нижняя оценка) Если S1 - S2 >= 10^(-5) перейти к шагу 2; ( нужная точность еще не достигнута ) Напечатать результат (S1 + S2) / 2
При реализации этого алгоритма на машине следует помнить, что ряд Грегори сходится достаточно медленно, и поэтому n может принимать довольно большие значения.
Для вычисления сколько-нибудь большого количества знаков пи предыдущий способ уже не годится. Но существует большое количество последовательностей, сходящихся к Пи гораздо быстрее. Воспользуемся, например, формулой Гаусса:
p | = 12arctan | 1 | + 8arctan | 1 | - 5arctan | 1 |
4 | 18 | 57 | 239 |
Доказательство этой формулы несложное, поэтому мы его опустим.
Исходник программы, включающий в себя 'длинную арифметику'
Программа вычисляет NbDigits первых цифр числа Пи. Функция вычисления arctan названа arccot, так как arctan(1/p) = arccot(p), но расчет происходит по формуле Тейлора именно для арктангенса, а именно arctan(x) = x - x 3 /3 + x 5 /5 - . x=1/p, значит arccot(x) = 1/p - 1 / p 3 / 3 + . Вычисления происходят рекурсивно: предыдущий элемент суммы делится и дает следующий.
/* ** Pascal Sebah : September 1999 ** ** Subject: ** ** A very easy program to compute Pi with many digits. ** No optimisations, no tricks, just a basic program to learn how ** to compute in multiprecision. ** ** Formulae: ** ** Pi/4 = arctan(1/2)+arctan(1/3) (Hutton 1) ** Pi/4 = 2*arctan(1/3)+arctan(1/7) (Hutton 2) ** Pi/4 = 4*arctan(1/5)-arctan(1/239) (Machin) ** Pi/4 = 12*arctan(1/18)+8*arctan(1/57)-5*arctan(1/239) (Gauss) ** ** with arctan(x) = x - x^3/3 + x^5/5 - . ** ** The Lehmer's measure is the sum of the inverse of the decimal ** logarithm of the pk in the arctan(1/pk). The more the measure ** is small, the more the formula is efficient. ** For example, with Machin's formula: ** ** E = 1/log10(5)+1/log10(239) = 1.852 ** ** Data: ** ** A big real (or multiprecision real) is defined in base B as: ** X = x(0) + x(1)/B^1 + . + x(n-1)/B^(n-1) ** where 0 Work with double instead of long and the base B can ** be choosen as 10^8 ** => During the iterations the numbers you add are smaller ** and smaller, take this in account in the +, *, / ** => In the division of y=x/d, you may precompute 1/d and ** avoid multiplications in the loop (only with doubles) ** => MaxDiv may be increased to more than 3000 with doubles ** => . */ #include #include #include #include long B=10000; /* Working base */ long LB=4; /* Log10(base) */ long MaxDiv=450; /* about sqrt(2^31/B) */ /* ** Set the big real x to the small integer Integer */ void SetToInteger (long n, long *x, long Integer) < long i; for (i=1; i/* ** Is the big real x equal to zero ? */ long IsZero (long n, long *x) < long i; for (i=0; i/* ** Addition of big reals : x += y ** Like school addition with carry management */ void Add (long n, long *x, long *y) < long carry=0, i; for (i=n-1; i>=0; i--) < x[i] += y[i]+carry; if (x[i]> > /* ** Substraction of big reals : x -= y ** Like school substraction with carry management ** x must be greater than y */ void Sub (long n, long *x, long *y) < long i; for (i=n-1; i>=0; i--) < x[i] -= y[i]; if (x[i]<0) < if (i) < x[i] += B; x[i-1]--; >> > > /* ** Multiplication of the big real x by the integer q ** x = x*q. ** Like school multiplication with carry management */ void Mul (long n, long *x, long q) < long carry=0, xi, i; for (i=n-1; i>=0; i--) < xi = x[i]*q; xi += carry; if (xi>=B) < carry = xi/B; xi -= (carry*B); >else carry = 0; x[i] = xi; > > /* ** Division of the big real x by the integer d ** The result is y=x/d. ** Like school division with carry management ** d is limited to MaxDiv*MaxDiv. */ void Div (long n, long *x, long d, long *y) < long carry=0, xi, q, i; for (i=0; i> /* ** Find the arc cotangent of the integer p (that is arctan (1/p)) ** Result in the big real x (size n) ** buf1 and buf2 are two buffers of size n */ void arccot (long p, long n, long *x, long *buf1, long *buf2) < long p2=p*p, k=3, sign=0; long *uk=buf1, *vk=buf2; SetToInteger (n, x, 0); SetToInteger (n, uk, 1); /* uk = 1/p */ Div (n, uk, p, uk); Add (n, x, uk); /* x = uk */ while (!IsZero(n, uk)) < if (p/* One step for small p */ else < Div (n, uk, p, uk); /* Two steps for large p (see division) */ Div (n, uk, p, uk); > /* uk = u(k-1)/(p^2) */ Div (n, uk, k, vk); /* vk = uk/k */ if (sign) Add (n, x, vk); /* x = x+vk */ else Sub (n, x, vk); /* x = x-vk */ k+=2; sign = 1-sign; > > /* ** Print the big real x */ void Print (long n, long *x) < long i; printf ("%d.", x[0]); for (i=1; iprintf ("\n"); > /* ** Computation of the constant Pi with arctan relations */ void main () < clock_t endclock, startclock; long NbDigits=10000, NbArctan; long p[10], m[10]; long size=1+NbDigits/LB, i; long *Pi = (long *)malloc(size*sizeof(long)); long *arctan = (long *)malloc(size*sizeof(long)); long *buffer1 = (long *)malloc(size*sizeof(long)); long *buffer2 = (long *)malloc(size*sizeof(long)); startclock = clock(); /* ** Formula used: ** ** Pi/4 = 12*arctan(1/18)+8*arctan(1/57)-5*arctan(1/239) (Gauss) */ NbArctan = 3; m[0] = 12; m[1] = 8; m[2] = -5; p[0] = 18; p[1] = 57; p[2] = 239; SetToInteger (size, Pi, 0); /* ** Computation of Pi/4 = Sum(i) [m[i]*arctan(1/p[i])] */ for (i=0; i0) Add (size, Pi, arctan); else Sub (size, Pi, arctan); > Mul (size, Pi, 4); endclock = clock (); Print (size, Pi); /* Print out of Pi */ printf ("Computation time is : %9.2f seconds\n", (float)(endclock-startclock)/(float)CLOCKS_PER_SEC ); free (Pi); free (arctan); free (buffer1); free (buffer2); >
Конечно, это не самые эффективные способы вычисления числа пи. Существует еще громадное количество формул. Например, формула Чудновского (Chudnovsky), разновидности которой используются в Maple. Однако в обычной практике программирования формулы Гаусса вполне хватает, поэтому эти методы не будут описываться в статье. Вряд ли кто-то хочет вычислять миллиарды знаков пи, для которых сложная формула дает большое увеличение скорости.
Вычисление числа пи
Нужно написать программу для вычисления числа пи по формуле p=4-4/3+4/5-4/7. чтобы программа подсчитывала число пи с введенным пользователем количеством знаков после запятой.Не понимаю, даже как начать ее писать.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Вычисление факториала и вычисление степени числа
Нужно проверить правильность сделанной программы если не правильно помогите исправить. Var.
Вычисление выражения для заданных натурального числа n и действительного числа x
Составить блок – схему алгоритма и программу вычисления выражения для заданных натурального числа .
Вычисление суммы четных делителей натурального числа М, больших числа Р
Помогите, пожалуйста составить программу на языке python.:) Составьте программу вычисления суммы.
Вычисление простых делителей натурального числа N, не являющихся делителями числа М
Помогите, пожалуйста, составить программу, язык программирования python Составить программу.
584 / 408 / 134
Регистрация: 02.10.2008
Сообщений: 1,727
Записей в блоге: 1
Начни с уточнения ТЗ.
Пользователь может ведь и 1000 ввести(привет плавающей арифметике), а может ввести и "не знаю"
З.Ы. А так поиск рулит по "Ряд Мадхавы-Лейбница на Си"
2074 / 1169 / 486
Регистрация: 11.10.2018
Сообщений: 5,895
На кого учитесь?
Добавлено через 37 минут
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#include #include int main() { int n = -1, Cnt = 0; double s = -2, eps = 1e-5, d = -2; char Znak = -1; while(fabs(d) >= eps) { s += Znak*d; n++; d = (double)1/(2*n+1); Znak = -Znak; Cnt++; } s *= 4; printf("s = %lf\n", s); printf("\nCnt = %d\n", Cnt); return 0; }
Регистрация: 20.07.2020
Сообщений: 3
На физическом факультете, спасибо
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Вычисление суммы четных делителей натурального числа М, больших числа Р
составить программу вычисления суммы четных делителей натурального числа М,больших числа Р,но.
Вычисление суммы нечетных чисел, больше числа А но меньших числа В
Написатт программу вычисление суммы нечетных чисел. Больших числа А но меньше числа В.
Вычисление значения целого числа по заданной строке символов, являющейся записью этого числа в 16-ричной с/с
Составить процедуру вычисления значения целого числа по заданной строке символов, являющейся.
Вычисление степени числа и запись цифр степени числа в массив
помогите пожалуйста) написать программу для вычисления степени числа и записью цифр степени этого.
Вычисление числа П
Нужна программа на C, вычисляющая число "ПИ" ну или хотя бы карказ ( с объяснением построчно, если.
Глава 6. Вычисление числа π
Одиннадцать первых цифр числа π = 3,1415926535… легко запомнить с помощью такой мнемоники:
«Кто и шутя и скоро пожелаетъ пи узнать число, ужъ знаетъ».
Её придумали до реформы русской орфографии 1918 года, поэтому и буквы «ѥръ» в конце слов после согласных.
Для приближённого вычисления числа π применяются разные методы.
Один из способов (на практике не очень удобный) связан с вычислением бесконечной суммы (ряда) Лейбница: 1 − 1 3 + 1 5 − 1 7 + … = ∑ i = 0 ∞ − 1 i 2 i + 1 = π 4 .
Можно получить π из суммы другого ряда — ряда Эйлера: 1 + 1 2 2 + 1 3 2 + … = ∑ i = 1 ∞ 1 i 2 = π 2 6 .
Естественно, на компьютере невозможно осуществить вычисление бесконечной суммы. Однако в математическом анализе доказывается, что оба ряда сходятся. Это значит, что последовательности частных сумм стремятся к некоторым числам (в наших примерах к π 4 и π 2 6 ), то есть сумма достаточно большого количества слагаемых ряда даст хорошее приближение для суммы. Задавшись требуемой точностью, можно даже указать необходимые количества слагаемых, чтобы обеспечить вычисление с этой точностью (конечно, без учёта ошибок округления при выполнении арифметических действий — такие ошибки очень трудно контролировать).
Рассмотрим геометрическую прогрессию со знаменателем − 1 : 1 − 1 + 1 − 1 + … Найдём её сумму S : S = 1 − 1 + 1 − 1 + … = 1 − 1 − 1 + 1 − … . Заметим, что выражение в скобках ничем не отличается от выражения для S : S = 1 − S . Отсюда находим, что S = 1 2 .
Всё это очень странно…
Сходится не всякий ряд. Единственный ряд, изучаемый в школе — геометрическая прогрессия: 1 + q + q 2 + q 3 + q 4 + … = ∑ i = 0 ∞ q i . Его сходимость зависит от q : ряд сходится лишь при q < 1 . В этом случае сумма, как известно, равна 1 1 − q .
Для сходимости необходимо, чтобы последовательность слагаемых стремилась к нулю. Но это условие не является достаточным.
Наряду с бесконечными суммами (рядами) рассматривают также бесконечные произведения и другие бесконечные выражения.
Как вывести число Пи до определенного знака?
Если требуется значительное количество знаков, придется считать пи самому.
8 июн 2018 в 20:08
Можно записать в строку значение откуда-нибудь из Википедии с кучей знаков, и выводить столько знаков сколько вам нужно. Только не забывать округлять последний знак.
8 июн 2018 в 20:52
Вообще-то в стандартной библиотеке нет готовой константы для Пи. Т.е. нет никакого M_PI . Тут в первую очередь надо выяснить, что именно вам надо сделать. Если у вас это учебное задание, то, боюсь, оно состоит как раз в том, чтобы вычислить заданное количество знаков числа Пи самостоятельно.