Am'm în căutarea pentru cel mai rapid mod de a obține valoarea lui π, ca pe o provocare personală. Mai precis, am'm, folosind metode care nu't implica utilizarea #define
constante ca M_PI
, sau hard-codare numărul în.
Programul de mai jos teste diferite moduri știu. Inline assembly versiune este, în teorie, cel mai rapid opțiune, deși în mod clar nu este portabil. Am'am inclus-o ca o referință pentru a compara împotriva altor versiuni. În testele mele, cu built-in-uri, 4 * atan(1)
versiune este mai rapidă pe GCC 4.2, pentru că auto-falduri atan(1) într-o constantă. Cu
-fno-internaspecificat
atan2(0, -1)` versiune este mai rapidă.
Aici's principalul program de testare (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;
}
Și inline assembly chestii (fldpi.c
), care va funcționa doar pentru sisteme x86 și x64:
double
fldpi()
{
double pi;
asm("fldpi" : "=t" (pi));
return pi;
}
Și de a construi script-ul care se bazează toate configurațiile I'm de testare (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
În afară de testare între diverse compilatorul (I'am comparat 32-bit împotriva 64-bit pentru că optimizările sunt diferite), am'am încercat, de asemenea, de comutare ordinea de teste în jurul valorii de. Dar totuși, atan2(0, -1)
versiune mai iese pe partea de sus de fiecare dată.
La metoda Monte Carlo, după cum sa menționat, se aplică unele mare de concepte, dar este, în mod clar, nu cel mai rapid, nu de o lovitură de lungă, nu de orice măsură rezonabilă. De asemenea, totul depinde de ce fel de precizie sunteți în căutarea pentru. Cel mai rapid π știu de este cel cu cifre greu codificate. Se uită la Pi și Pi[PDF], există o mulțime de formule.
Aici este o metodă care converge rapid — aproximativ 14 cifre fiecare iterație. PiFast, cel mai rapid aplicația, folosește această formulă cu FFT. Am'll scrie formula, deoarece codul este simplu. Această formulă a fost gasit aproape de Ramanujan și descoperit de Chudnovsky. Acesta este, de fapt cum a calculat de mai multe miliarde de cifre ale numărului — e't o metodă de a ignora. Formula va revărsa ușor și, din moment ce suntem împărțirea factorialele, ar fi avantajoasă atunci să amâne astfel de calcule pentru a elimina termeni.
în cazul în care,
Mai jos este Brent–Salamin algoritmul. Wikipedia menționează că, atunci când o și b sunt "destul de aproape" atunci (a + b)² / 4t va fi o aproximare a lui π. Am'm nu sunt sigur ce "destul de aproape" înseamnă, dar din testele mele, o repetare a primit 2 cifre, două luat 7, iar trei au avut 15, desigur, acest lucru este cu dublu, deci ar putea fi o eroare, pe baza de reprezentare și adevărat calcul ar putea fi mai precisă.
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)
În cele din urmă, cum despre unele pi golf (800 cifre)? 160 de caractere!
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);}
Îmi place foarte mult acest program, pentru că acesta aproximează π uitandu-se la propria sa zonă.
IOCCC 1988 : westley.c
define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3 f\n",4.*-F/OO/OO);}FOO() { --- -------- ----------- ------------- -------------- -------------- --------------- --------------- --------------- --------------- -------------- -------------- ------------- ----------- ------- --- }
Aici's-o descriere generală a unei tehnica de calcul pi care le-am învățat în liceu.
Vreau doar să împărtășească acest lucru pentru că eu cred că este destul de simplu că oricine poate să-l amintesc, pe termen nelimitat, plus că te învață conceptul de "Monte-Carlo" metode-care sunt metodele statistice de a ajunge la răspunsurile pe care don't apar imediat să fie dedus prin procese aleatorii.
Desenați un pătrat, și înscrie un cadran (un sfert de un semi-cerc) în interiorul pătrat (un arc de cerc cu raza egală cu latura pătratului, astfel încât umple cât mai mult din piața posibil)
Acum arunca o săgeată în pătrat, și de a înregistra în cazul în care acesta a terenurilor-care este, pentru a alege un punct oarecare oriunde în interiorul pătrat. Desigur, a aterizat în interiorul pătrat, dar este în semi-cerc? Să înregistreze acest fapt.
Repetați acest proces de mai multe ori ... și veți găsi acolo este un raport de numărul de puncte din interiorul semi-cerc față de numărul total aruncat, numim acest raport x.
Deoarece zona de pătrat este de r ori r, se poate deduce că zona de semi cerc este de x ori r ori r (care este, de x ori r pătrat). Prin urmare, x 4 ori va da pi.
Aceasta nu este o metodă rapidă de a utiliza. Dar's un frumos exemplu de metoda Monte Carlo. Și dacă te uiți în jur, s-ar putea găsi că multe probleme în caz contrar, în afara abilități de calcul pot fi rezolvate prin astfel de metode.
Din motive de exhaustivitate, un C++ versiunea șablon, care, pentru o construcție optimizată, se va calcula o aproximare de PI la compilare, și va inline la o singură valoare.
#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;
}
Notă pentru am > 10, optimizat construiește poate fi lentă, de asemenea, pentru non-optimizat ruleaza. Pentru 12 iterații cred că există în jur de 80k apeluri la valoarea() (în absența memoisation).
Nu's, de fapt, o carte întreagă dedicată (printre alte lucruri) a rapid metode de calcul al \pi: 'Pi și AGM', de Jonathan și Peter Borwein (disponibil pe Amazon).
Am studiat AGM și legate de algoritmi destul de un pic: it's destul de interesant (deși, uneori, non-trivial).
Rețineți că, pentru a implementa cele mai moderne algoritmi pentru a calcula \pi, veți avea nevoie de un multiprecision biblioteca aritmetică (GMP este destul de o alegere bună, deși l's a fost un timp de când nu am mai folosit-o).
Ora-complexitate dintre cele mai bune algoritmi este în O(M(n)log(n)), unde M(n) este timpul de complexitate pentru înmulțirea a două n-bit numere întregi (M(n)=O(n log(n) log(log(n))), folosind FFT pe baza de algoritmi, care sunt de obicei necesare atunci când se calculează cifrele de \pi, și un astfel de algoritm este implementat în GMP).
Rețineți că, chiar dacă matematica din spatele algoritmilor-ar putea să nu fie banal, algoritmii ei înșiși sunt, de obicei, câteva linii de pseudo-cod, și punerea lor în aplicare este de obicei foarte simplă (dacă ați ales să nu scrie propriile multiprecision aritmetică :-) ).
Următoarele răspunsuri exact cum să facă acest lucru în cel mai rapid mod posibil-cu puțin efort de calcul. Chiar dacă tu nu't ca răspuns, trebuie să recunosc că este într-adevăr cel mai rapid mod de a obține valoarea lui PI.
La RAPID mod pentru a obține valoarea lui Pi este:
În cazul în care nu't au o bibliotecă Matematica la îndemână..
La MAI mod (mai mult o soluție universală) este:
uită-te în sus Pi pe Internet, de exemplu aici:
http://www.eveandersson.com/pi/digits/1000000 (1 milion de cifre .. ce's ta în virgulă mobilă de precizie? )
sau aici:
http://3.141592653589793238462643383279502884197169399375105820974944592.com/
sau aici:
http://en.wikipedia.org/wiki/Pi
L's foarte repede pentru a găsi cifrele de care aveți nevoie pentru orice precizie aritmetică doriți să utilizați, și, prin definirea unei constante, puteți asigurați-vă că don't deșeuri prețioase de timp de PROCESOR.
Nu numai ca aceasta este o parte plină de umor a răspuns, dar în realitate, dacă cineva ar merge mai departe și de a calcula valoarea de Pi într-o aplicație reală .. asta ar fi o mare pierdere de timp de PROCESOR, nu't-l? Cel puțin eu nu't vedea o aplicație reală pentru încercarea de a re-calcula acest lucru.
Stimate Moderator: vă rugăm să rețineți că OPERAȚIUNEA a întrebat: "cel mai Rapid Mod de a obține valoarea de PI"
Tocmai a dat peste una pe care ar trebui să fie aici pentru completare:
Ea are destul de frumos proprietatea că precizia poate fi îmbunătățită a face programul mai mare.
Aici's unele introspecție în limba în sine
Dacă acest articol este adevărat, atunci algoritm care Bellard s-au creat ar putea fi una dintre cele mai rapide disponibile. El a creat pi la 2,7 MILIARDE de cifre folosind un PC DESKTOP!
...și a publicat lui lucreze aici
Bună treabă Bellard, sunt pionier!
Aceasta este o "clasic" metodă, foarte ușor să pună în aplicare. Această punere în aplicare, în python (nu asa de repede limba) e:
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)
Puteți găsi mai multe informații aici.
Oricum cel mai rapid mod de a obține o precizie cât mai-mult-ca-tine-vreau cu valoare de pi în python este:
from gmpy import pi
print pi(3000) # the rule is the same as
# the precision on the previous code
aici este o bucată de sursă pentru gmpy pi metoda, eu nu't cred că codul este la fel de util ca un comentariu în acest caz:
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;
}
EDIT: am avut unele probleme cu cut și paste și identation, oricum puteți găsi sursa aici.
Dacă prin cel mai rapid înseamnă mai rapid să tastați în codul, aici's golfscript soluție:
;''6666,-2%{2+.2/@*\/10.3??2*+}*`1000<~\;
Utilizați Machin-ca formula
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.
Puse în aplicare în Sistem, de exemplu:
(+ (- (+ (* 176 (atan (/ 1 57))) (* 28 (atan (/ 1 239)))) (* 48 (atan (/ 1 682)))) (* 96 (atan (/ 1 12943))))
Dacă sunteți dispus să utilizeze o aproximare, 355 / 113
este bun pentru 6 cifre zecimale, și are avantajul de a fi ușor de utilizat, cu expresii întregi. Ca's nu la fel de important în aceste zile, ca "în virgulă mobilă matematica co-procesor" a încetat să mai aibă vreun sens, dar a fost destul de important o dată.
Pi este exact 3! [Prof. Dr. Frink (The Simpsons)]
Glumă, dar aici's unul in C# (.NET Framework este necesar).
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;
}
}
}
Cu duble:
4.0 * (4.0 * Math.Atan(0.2) - Math.Atan(1.0 / 239.0))
Acest lucru va fi o acuratete de pana la 14 zecimale, suficient pentru a umple o cameră dublă (inexactitatea este, probabil, pentru că restul de zecimale în arc de cerc tangente sunt trunchiate).
De asemenea, Seth, l's 3.141592653589793238463, nu 64.
( Copiate de pe 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))) );
Această versiune (în Delphi) nu este nimic special, dar este cel puțin mai repede decât versiunea Nick Hodge a postat pe blogul său :). Pe masina mea, este nevoie de aproximativ 16 secunde pentru a face un miliard de iterații, oferind o valoare de 3.1415926525879 (exacte parte este în bold).
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.
Dacă doriți să calcul o aproximare a valorii π (din anumite motive), ar trebui să încercați un binar de extracție algoritm. Bellard's îmbunătățirea BBP dă nu PI în O(N^2).
Dacă doriți să obține o apropiere de valoarea lui π de-a face calcule, atunci:
PI = 3.141592654
Acordate, care's doar o aproximare, și nu în întregime corecte. L's de un pic mai mult decât 0.00000000004102. (patru de zece trilionimi, despre 4/10,000,000,000).
Dacă vrei să faci matematica cu π, atunci ia-ti un creion și o hârtie sau un computer algebra pachet, și de a folosi π's valoare exactă, π.
Dacă vrei într-adevăr o formulă, aceasta este distractiv:
Înapoi în zilele de demult, cu cuvântul de mici dimensiuni și lent sau inexistent de operațiuni în virgulă mobilă, am folosit pentru a face chestii de genul asta:
/* Return approximation of n * PI; n is integer */
#define pi_times(n) (((n) * 22) / 7)
Pentru aplicații care nu't necesită o mulțime de precizie (jocuri video, de exemplu), acest lucru este foarte rapid și este suficient de precisă.