Я'ищу самый быстрый способ получить значение π, в качестве личной задачи. Точнее, мне нужны способы, которые не включают использование констант #define
, таких как M_PI
, или жесткое кодирование числа.
Приведенная ниже программа тестирует различные известные мне способы. Версия на встроенном ассемблере, теоретически, является самым быстрым вариантом, хотя явно не переносимым. Я включил его в качестве базового варианта для сравнения с другими версиями. В моих тестах со встроенными модулями версия 4 * atan(1)
оказалась самой быстрой на GCC 4.2, потому что она автоматически складывает atan(1)
в константу. При указании -fno-builtin
быстрее всего работает версия atan2(0, -1)
.
Вот'основная программа тестирования (pitimes.c
):
#include <math.h>
#include <stdio.h>
#include <time.h>
#define ITERS 10000000
#define TESTWITH(x) { \
diff = 0.0; \
time1 = clock(); \
for (i = 0; i < ITERS; ++i) \
diff += (x) - M_PI; \
time2 = clock(); \
printf("%s\t=> %e, time => %f\n", #x, diff, diffclock(time2, time1)); \
}
static inline double
diffclock(clock_t time1, clock_t time0)
{
return (double) (time1 - time0) / CLOCKS_PER_SEC;
}
int
main()
{
int i;
clock_t time1, time2;
double diff;
/* Warmup. The atan2 case catches GCC's atan folding (which would
* optimise the ``4 * atan(1) - M_PI'' to a no-op), if -fno-builtin
* is not used. */
TESTWITH(4 * atan(1))
TESTWITH(4 * atan2(1, 1))
#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
extern double fldpi();
TESTWITH(fldpi())
#endif
/* Actual tests start here. */
TESTWITH(atan2(0, -1))
TESTWITH(acos(-1))
TESTWITH(2 * asin(1))
TESTWITH(4 * atan2(1, 1))
TESTWITH(4 * atan(1))
return 0;
}
И встроенный ассемблерный материал (fldpi.c
), который будет работать только для x86 и x64 систем:
double
fldpi()
{
double pi;
asm("fldpi" : "=t" (pi));
return pi;
}
И скрипт сборки, который собирает все конфигурации, которые я тестирую (build.sh
):
#!/bin/sh
gcc -O3 -Wall -c -m32 -o fldpi-32.o fldpi.c
gcc -O3 -Wall -c -m64 -o fldpi-64.o fldpi.c
gcc -O3 -Wall -ffast-math -m32 -o pitimes1-32 pitimes.c fldpi-32.o
gcc -O3 -Wall -m32 -o pitimes2-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -fno-builtin -m32 -o pitimes3-32 pitimes.c fldpi-32.o -lm
gcc -O3 -Wall -ffast-math -m64 -o pitimes1-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall -m64 -o pitimes2-64 pitimes.c fldpi-64.o -lm
gcc -O3 -Wall -fno-builtin -m64 -o pitimes3-64 pitimes.c fldpi-64.o -lm
Помимо тестирования между различными флагами компилятора (я'сравнивал 32-битный с 64-битным, потому что оптимизация разная), я'также пробовал менять порядок тестов. Но все равно, версия atan2(0, -1)
каждый раз выходит на первое место.
Метод Монте-Карло, как уже упоминалось, применяет некоторые замечательные концепции, но он явно не самый быстрый, не по большому счету, ни по каким разумным меркам. Кроме того, все зависит от того, какую точность вы ищете. Самый быстрый π, который я знаю, это тот, в котором цифры жестко закодированы. Если посмотреть на Pi и Pi[PDF], то там есть много формул.
Вот метод, который сходится быстро - около 14 цифр за итерацию. PiFast, самое быстрое на данный момент приложение, использует эту формулу с БПФ. Я просто напишу формулу, поскольку код прост. Эта формула была почти найдена Рамануджаном и открыта Чудновским. Именно так он вычислил несколько миллиардов цифр числа - так что этим методом не стоит пренебрегать. Формула быстро переполнится, и, поскольку мы делим факториал, было бы выгодно отложить такие вычисления для удаления членов.
где,
Ниже приведен алгоритм Брента-Саламина. Википедия упоминает, что когда a и b достаточно "близки", то (a + b)² / 4t будет приближением π. Я не уверен, что значит "достаточно близко", но из моих тестов, одна итерация дала 2 цифры, две - 7, а три - 15, конечно, это с двойными числами, так что это может иметь ошибку, основанную на его представлении, и истинный расчет может быть более точным.
let pi_2 iters =
let rec loop_ a b t p i =
if i = 0 then a,b,t,p
else
let a_n = (a +. b) /. 2.0
and b_n = sqrt (a*.b)
and p_n = 2.0 *. p in
let t_n = t -. (p *. (a -. a_n) *. (a -. a_n)) in
loop_ a_n b_n t_n p_n (i - 1)
in
let a,b,t,p = loop_ (1.0) (1.0 /. (sqrt 2.0)) (1.0/.4.0) (1.0) iters in
(a +. b) *. (a +. b) /. (4.0 *. t)
И, наконец, как насчет пи-гольфа (800 цифр)? 160 символов!
int a=10000,b,c=2800,d,e,f[2801],g;main(){for(;b-c;)f[b++]=a/5;for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);}
Мне действительно нравится эта программа, потому что она приближает π, смотря на его собственную область.
IOCCC 1988: < href =" http://www0.us.ioccc.org/1988/westley.c" > Вестли c
define _-F< 00 || - F-OO-;
международный F=00, OO=00; главный () {F_OO (); printf (" %1.3f\n" 4. *-F/OO/OO);} FOO () { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
Вот общее описание методики вычисления числа "пи", которую я изучал в средней школе.
Я делюсь им только потому, что считаю его достаточно простым, чтобы любой мог запомнить его на неопределенное время, плюс он учит вас концепции "методов Монте-Карло" - это статистические методы получения ответов, которые не сразу кажутся выводимыми через случайные процессы.
Нарисуйте квадрат и впишите в него квадрант (четверть полукруга) (квадрант с радиусом, равным стороне квадрата, чтобы он заполнил как можно большую часть квадрата).
Теперь бросьте дротик в квадрат и запишите, куда он приземлится - то есть выберите случайную точку в любом месте квадрата. Конечно, дротик приземлился внутри квадрата, но приземлился ли он внутри полукруга? Запишите этот факт.
Повторите этот процесс много раз - и вы обнаружите, что существует отношение числа точек внутри полукруга к общему числу брошенных дротиков, назовем это отношение x.
Поскольку площадь квадрата r умножить на r, можно сделать вывод, что площадь полукруга равна x умножить на r (то есть x умножить на r в квадрате). Следовательно, x умноженное на 4 даст число пи.
Этот метод нельзя назвать быстрым. Но это хороший пример метода Монте-Карло. И если вы посмотрите вокруг, вы можете обнаружить, что многие проблемы, которые в других случаях не под силу вашим вычислительным навыкам, могут быть решены с помощью таких методов.
В интересах полноты C ++ версия шаблона, которые, для оптимизированного строят, вычислит приближение ПИ во время компиляции, и будет действующий к единственной стоимости.
#include <iostream>
template<int I>
struct sign
{
enum {value = (I % 2) == 0 ? 1 : -1};
};
template<int I, int J>
struct pi_calc
{
inline static double value ()
{
return (pi_calc<I-1, J>::value () + pi_calc<I-1, J+1>::value ()) / 2.0;
}
};
template<int J>
struct pi_calc<0, J>
{
inline static double value ()
{
return (sign<J>::value * 4.0) / (2.0 * J + 1.0) + pi_calc<0, J-1>::value ();
}
};
template<>
struct pi_calc<0, 0>
{
inline static double value ()
{
return 4.0;
}
};
template<int I>
struct pi
{
inline static double value ()
{
return pi_calc<I, I>::value ();
}
};
int main ()
{
std::cout.precision (12);
const double pi_value = pi<10>::value ();
std::cout << "pi ~ " << pi_value << std::endl;
return 0;
}
Отметьте поскольку я > 10, оптимизированный строит, может быть медленным, аналогично для неоптимизированных пробегов. Для 12 повторений я полагаю, что есть вокруг требований 80k к стоимости () (в отсутствие memoisation).
There' s на самом деле целая посвященная книга (среди других вещей) к быстро методы для вычисления \pi: ' Пи и AGM' Джонатаном и Питером Борвейном ([доступный на Amazon] [1]).
Я изучил ЕЖЕГОДНОЕ ОБЩЕЕ СОБРАНИЕ и связал алгоритмы вполне немного: it' s довольно интересный (хотя иногда нетривиальный).
Обратите внимание, что, чтобы осуществить большинство современных алгоритмов, чтобы вычислить \pi, Вам будет нужна библиотека арифметики мультиточности (GMP вполне хороший выбор, хотя it' s некоторое время, так как я в последний раз использовал его).
Сложность времени лучших алгоритмов находится в O (M (n) регистрация (n)), где M (n) является сложностью времени для умножения двухn-битных целых чисел (M (n) =O (n регистрация (n) регистрация (регистрация (n))) использование основанных на FFT алгоритмов, которые обычно необходимы, когда вычислительные цифры \pi и такой алгоритм осуществлены в GMP).
Обратите внимание, что даже при том, что математика позади алгоритмов не могла бы быть тривиальной, сами алгоритмы обычно - несколько линий псевдокодекса, и их внедрение обычно очень прямое (если Вы приняли решение не написать свою собственную арифметику мультиточности:-)).
[1]: http://www.amazon.com/PI-AGM-Analytic-Computational-Complexity/dp/047131515X/" доступный на Amazon"
Следующие ответы точно, как сделать это самым быстрым способом - с наименее вычислительным усилием . Даже если Вы don' t как ответ, Вы должны признать, что это - действительно самый быстрый способ получить ценность ПИ.
САМЫЙ БЫСТРЫЙ способ получить ценность Пи:
В случае, если Вы don' у t есть Математическая библиотека под рукой..
ВТОРОЙ САМЫЙ БЫСТРЫЙ путь (более универсальное решение):
ищите Пи в Интернете, например, здесь:
http://www.eveandersson.com/pi/digits/1000000 (1 миллион цифр.. what' s Ваша точность с плавающей запятой?)
или здесь:
http://3.141592653589793238462643383279502884197169399375105820974944592.com/
или здесь:
http://en.wikipedia.org/wiki/Pi
It' s действительно быстро, чтобы найти цифры Вам нужно для любой арифметики точности, которую Вы хотели бы использовать, и определяя константу, Вы можете удостовериться что Вы don' t тратят впустую драгоценное время центрального процессора.
Мало того, что это - частично юмористический ответ, но и в действительности, если кто-либо шел бы вперед и вычислил бы ценность Пи в реальном применении.. это было бы довольно большой пустой тратой времени центрального процессора, wouldn' t это? По крайней мере, я don' t видят реальное заявление на попытку повторно вычислить это.
Дорогой Модератор: обратите внимание на то, что OP спросил: " Самый Быстрый Способ получить ценность PI"
Формула BBP позволяет Вам вычислять энную цифру - в основе 2 (или 16) - не имея необходимость даже беспокоиться предыдущими n-1 цифрами сначала:)
Вместо того, чтобы определить пи как константу, я всегда использую 'acos (-1)'.
Просто столкнулся с этим, который должен быть здесь для полноты:
У этого есть довольно хорошая собственность, что точность может быть улучшена, делая программу больше.
Здесь ' s некоторое понимание самого языка
Если эта статья верна, то алгоритм, который создал Bellard, мог быть одним из самых быстрых доступных. Он создал пи к 2,7 триллионам цифр, используя НАСТОЛЬНЫЙ PC!
... и он издал его работа здесь
Хорошая работа Bellard, Вы - пионер!
Это - " classic" метод, очень легкий осуществить. Это внедрение, у питона (не так быстрый язык) делает это:
from math import pi
from time import time
precision = 10**6 # higher value -> higher precision
# lower value -> higher speed
t = time()
calc = 0
for k in xrange(0, precision):
calc += ((-1)**k) / (2*k+1.)
calc *= 4. # this is just a little optimization
t = time()-t
print "Calculated: %.40f" % calc
print "Costant pi: %.40f" % pi
print "Difference: %.40f" % abs(calc-pi)
print "Time elapsed: %s" % repr(t)
Вы можете найти больше информации здесь.
Так или иначе самый быстрый способ получить точное так, как Вы хотите ценность пи у питона:
from gmpy import pi
print pi(3000) # the rule is the same as
# the precision on the previous code
вот часть источника для gmpy метода пи, я don' t думают, что кодекс так же полезен как комментарий в этом случае:
static char doc_pi[]="\
pi(n): returns pi with n bits of precision in an mpf object\n\
";
/* This function was originally from netlib, package bmp, by
* Richard P. Brent. Paulo Cesar Pereira de Andrade converted
* it to C and used it in his LISP interpreter.
*
* Original comments:
*
* sets mp pi = 3.14159... to the available precision.
* uses the gauss-legendre algorithm.
* this method requires time o(ln(t)m(t)), so it is slower
* than mppi if m(t) = o(t**2), but would be faster for
* large t if a faster multiplication algorithm were used
* (see comments in mpmul).
* for a description of the method, see - multiple-precision
* zero-finding and the complexity of elementary function
* evaluation (by r. p. brent), in analytic computational
* complexity (edited by j. f. traub), academic press, 1976, 151-176.
* rounding options not implemented, no guard digits used.
*/
static PyObject *
Pygmpy_pi(PyObject *self, PyObject *args)
{
PympfObject *pi;
int precision;
mpf_t r_i2, r_i3, r_i4;
mpf_t ix;
ONE_ARG("pi", "i", &precision);
if(!(pi = Pympf_new(precision))) {
return NULL;
}
mpf_set_si(pi->f, 1);
mpf_init(ix);
mpf_set_ui(ix, 1);
mpf_init2(r_i2, precision);
mpf_init2(r_i3, precision);
mpf_set_d(r_i3, 0.25);
mpf_init2(r_i4, precision);
mpf_set_d(r_i4, 0.5);
mpf_sqrt(r_i4, r_i4);
for (;;) {
mpf_set(r_i2, pi->f);
mpf_add(pi->f, pi->f, r_i4);
mpf_div_ui(pi->f, pi->f, 2);
mpf_mul(r_i4, r_i2, r_i4);
mpf_sub(r_i2, pi->f, r_i2);
mpf_mul(r_i2, r_i2, r_i2);
mpf_mul(r_i2, r_i2, ix);
mpf_sub(r_i3, r_i3, r_i2);
mpf_sqrt(r_i4, r_i4);
mpf_mul_ui(ix, ix, 2);
/* Check for convergence */
if (!(mpf_cmp_si(r_i2, 0) &&
mpf_get_prec(r_i2) >= (unsigned)precision)) {
mpf_mul(pi->f, pi->f, r_i4);
mpf_div(pi->f, pi->f, r_i3);
break;
}
}
mpf_clear(ix);
mpf_clear(r_i2);
mpf_clear(r_i3);
mpf_clear(r_i4);
return (PyObject*)pi;
}
ОТРЕДАКТИРУЙТЕ: У меня была некоторая проблема с вырезанным и вставленным и identation, так или иначе Вы можете найти источник здесь.
Если под самым быстрым вы подразумеваете самый быстрый ввод кода, то вот golfscript решение:
;''6666,-2%{2+.2/@*\/10.3??2*+}*`1000<~\;
Используйте подобную Machin формулу
176 * arctan (1/57) + 28 * arctan (1/239) - 48 * arctan (1/682) + 96 * arctan(1/12943)
[; \left( 176 \arctan \frac{1}{57} + 28 \arctan \frac{1}{239} - 48 \arctan \frac{1}{682} + 96 \arctan \frac{1}{12943}\right) ;], for you TeX the World people.
Осуществленный в Схеме, например:
'(+ (-(+ ( 176 (atan (/1 57))) ( 28 (atan (/1 239)))) ( 48 (atan (/1 682)))) ( 96 (atan (/1 12943))))'
Если Вы готовы использовать приближение, '355 / 113' хорошо для 6 десятичных цифр и имеет добавленное преимущество того, чтобы быть применимым с выражениями целого числа. That' s не столь важный в эти дни, как " математика с плавающей запятой co-processor" прекращенный, чтобы иметь любое значение, но это было довольно важно однажды.
Пи равняется точно 3! [Профессор Фринк (Симпсоны)]
Шутка, но here' s один в C# (Требуемая.NET-структура).
using System;
using System.Text;
class Program {
static void Main(string[] args) {
int Digits = 100;
BigNumber x = new BigNumber(Digits);
BigNumber y = new BigNumber(Digits);
x.ArcTan(16, 5);
y.ArcTan(4, 239);
x.Subtract(y);
string pi = x.ToString();
Console.WriteLine(pi);
}
}
public class BigNumber {
private UInt32[] number;
private int size;
private int maxDigits;
public BigNumber(int maxDigits) {
this.maxDigits = maxDigits;
this.size = (int)Math.Ceiling((float)maxDigits * 0.104) + 2;
number = new UInt32[size];
}
public BigNumber(int maxDigits, UInt32 intPart)
: this(maxDigits) {
number[0] = intPart;
for (int i = 1; i < size; i++) {
number[i] = 0;
}
}
private void VerifySameSize(BigNumber value) {
if (Object.ReferenceEquals(this, value))
throw new Exception("BigNumbers cannot operate on themselves");
if (value.size != this.size)
throw new Exception("BigNumbers must have the same size");
}
public void Add(BigNumber value) {
VerifySameSize(value);
int index = size - 1;
while (index >= 0 && value.number[index] == 0)
index--;
UInt32 carry = 0;
while (index >= 0) {
UInt64 result = (UInt64)number[index] +
value.number[index] + carry;
number[index] = (UInt32)result;
if (result >= 0x100000000U)
carry = 1;
else
carry = 0;
index--;
}
}
public void Subtract(BigNumber value) {
VerifySameSize(value);
int index = size - 1;
while (index >= 0 && value.number[index] == 0)
index--;
UInt32 borrow = 0;
while (index >= 0) {
UInt64 result = 0x100000000U + (UInt64)number[index] -
value.number[index] - borrow;
number[index] = (UInt32)result;
if (result >= 0x100000000U)
borrow = 0;
else
borrow = 1;
index--;
}
}
public void Multiply(UInt32 value) {
int index = size - 1;
while (index >= 0 && number[index] == 0)
index--;
UInt32 carry = 0;
while (index >= 0) {
UInt64 result = (UInt64)number[index] * value + carry;
number[index] = (UInt32)result;
carry = (UInt32)(result >> 32);
index--;
}
}
public void Divide(UInt32 value) {
int index = 0;
while (index < size && number[index] == 0)
index++;
UInt32 carry = 0;
while (index < size) {
UInt64 result = number[index] + ((UInt64)carry << 32);
number[index] = (UInt32)(result / (UInt64)value);
carry = (UInt32)(result % (UInt64)value);
index++;
}
}
public void Assign(BigNumber value) {
VerifySameSize(value);
for (int i = 0; i < size; i++) {
number[i] = value.number[i];
}
}
public override string ToString() {
BigNumber temp = new BigNumber(maxDigits);
temp.Assign(this);
StringBuilder sb = new StringBuilder();
sb.Append(temp.number[0]);
sb.Append(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator);
int digitCount = 0;
while (digitCount < maxDigits) {
temp.number[0] = 0;
temp.Multiply(100000);
sb.AppendFormat("{0:D5}", temp.number[0]);
digitCount += 5;
}
return sb.ToString();
}
public bool IsZero() {
foreach (UInt32 item in number) {
if (item != 0)
return false;
}
return true;
}
public void ArcTan(UInt32 multiplicand, UInt32 reciprocal) {
BigNumber X = new BigNumber(maxDigits, multiplicand);
X.Divide(reciprocal);
reciprocal *= reciprocal;
this.Assign(X);
BigNumber term = new BigNumber(maxDigits);
UInt32 divisor = 1;
bool subtractTerm = true;
while (true) {
X.Divide(reciprocal);
term.Assign(X);
divisor += 2;
term.Divide(divisor);
if (term.IsZero())
break;
if (subtractTerm)
this.Subtract(term);
else
this.Add(term);
subtractTerm = !subtractTerm;
}
}
}
С удваивается:
4.0 * (4.0 * Math.Atan(0.2) - Math.Atan(1.0 / 239.0))
Это будет точно до 14 десятичных разрядов, достаточно чтобы заполнить двойное (погрешность, вероятно, потому что остальная часть десятичных чисел в арктангенсах усеченная).
Также Сет, it' s 3.14159265358979323846< b> 3 не 64.
(Скопированный с DSource.org)
/** Calculate pi at compile time
*
* Compile with dmd -c pi.d
*/
module calcpi;
import meta.math;
import meta.conv;
/** real evaluateSeries!(real x, real metafunction!(real y, int n) term)
*
* Evaluate a power series at compile time.
*
* Given a metafunction of the form
* real term!(real y, int n),
* which gives the nth term of a convergent series at the point y
* (where the first term is n==1), and a real number x,
* this metafunction calculates the infinite sum at the point x
* by adding terms until the sum doesn't change any more.
*/
template evaluateSeries(real x, alias term, int n=1, real sumsofar=0.0)
{
static if (n>1 && sumsofar == sumsofar + term!(x, n+1)) {
const real evaluateSeries = sumsofar;
} else {
const real evaluateSeries = evaluateSeries!(x, term, n+1, sumsofar + term!(x, n));
}
}
/*** Calculate atan(x) at compile time.
*
* Uses the Maclaurin formula
* atan(z) = z - z^3/3 + Z^5/5 - Z^7/7 + ...
*/
template atan(real z)
{
const real atan = evaluateSeries!(z, atanTerm);
}
template atanTerm(real x, int n)
{
const real atanTerm = (n & 1 ? 1 : -1) * pow!(x, 2*n-1)/(2*n-1);
}
/// Machin's formula for pi
/// pi/4 = 4 atan(1/5) - atan(1/239).
pragma(msg, "PI = " ~ fcvt!(4.0 * (4*atan!(1/5.0) - atan!(1/239.0))) );
Эта версия (в Дельфи) является ничем специальным, но это, по крайней мере, быстрее, чем версия Ник Ходж, размещенный в его блоге:). На моей машине требуется приблизительно 16 секунд, чтобы сделать миллиард повторений, давая ценность 3.14159265 25879 (точная часть находится в смелом).
program calcpi;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
start, finish: TDateTime;
function CalculatePi(iterations: integer): double;
var
numerator, denominator, i: integer;
sum: double;
begin
{
PI may be approximated with this formula:
4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 .......)
//}
numerator := 1;
denominator := 1;
sum := 0;
for i := 1 to iterations do begin
sum := sum + (numerator/denominator);
denominator := denominator + 2;
numerator := -numerator;
end;
Result := 4 * sum;
end;
begin
try
start := Now;
WriteLn(FloatToStr(CalculatePi(StrToInt(ParamStr(1)))));
finish := Now;
WriteLn('Seconds:' + FormatDateTime('hh:mm:ss.zz',finish-start));
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
Если Вы хотите к , вычисляют приближение ценности π (по некоторым причинам), Вы должны попробовать двойной алгоритм извлечения. < href =" http://en.wikipedia.org/wiki/Bellard%27s_formula" > Bellard' s улучшение < href =" http://en.wikipedia.org/wiki/Bailey–Borwein–Plouffe_formula" > BBP дает делает ПИ в O (N^2).
Если Вы хотите к , получают приближение ценности π, чтобы сделать вычисления, то:
PI = 3.141592654
Предоставленный, that' s только приближение, и не совсем точный. It' s прочь немного больше чем 0,00000000004102. (четыре десять-trillionths, о < sup> 4/< sub> 10,000,000,000).
Если Вы хотите сделать математика с π, затем вовлечь себя карандаш и бумага или компьютерный пакет алгебры, и использовать π' s точная стоимость, π.
Если Вы действительно хотите формулу, этот - забава:
Назад в былые времена, с небольшими размерами слова и медленными или несуществующими операциями с плавающей запятой, мы раньше делали материал как это:
/* Return approximation of n * PI; n is integer */
#define pi_times(n) (((n) * 22) / 7)
Для заявлений это don' t требуют большой точности (видеоигры, например), это очень быстро и достаточно точно.