No Sólo Cuentas

Aproximando pi

Creado el domingo 13 de julio de 2025
Modificado por última vez el domingo 13 de julio de 2025

El número \(\pi\) es un número irracional. Hay quien lo aproxima por 3'14, otros por 3'1416; hay quien incluso lo aproxima por 3. Cualquier representación decimal que hagamos será una aproximación, porque el número \(\pi\) tiene infinitos decimales que no siguien un patrón fácilmente denotable. Así que lo aproximamos por números racionales, que como mínimo podemos expresar como cociente entre dos números enteros. El número 3'14 es \(\frac{314}{100}\), fracción reducible a \(\frac{157}{50}\); el número 3'1416 es \(\frac{31416}{10000}\) o \(\frac{3927}{1250}\); el número 3 es \(\frac{3}{1}\). Cuanto más dígitos decimales de \(\pi\) consideremos, más nos acercaremos al valor real del número, pero estaremos usando números cada vez más engorrosos como \(\frac{3927}{1250}\). Así que ganamos en precisión pero perdemos en comodidad.

Sólo que en realidad esto no es así. Podemos tener fracciones con números más pequeños que aproximen mejor. Por ejemplo, la diferencia entre \(\pi\) y la fracción \(\frac{157}{50}\) es aproximadamente 0'001593; sin embargo, la diferencia entre \(\pi\) y la fracción \(\frac{22}{7}\), que es una fracción significativamente más “sencilla” que la anterior, es de aproximadamente -0'001264. Olvidándonos del signo, que lo único que nos dice es si la fracción está justo por debajo o justo por encima de \(\pi\), lo que tenemos es dos fracciones en la que la que tiene numerador y denominador más pequeños da una aproximación más cercana a \(\pi\). La fracción \(\frac{3927}{1250}\) también es mejorable: su distancia a \(\pi\) es de 7'3464e-6, pero resulta que la fracción \(\frac{355}{113}\), de números más pequeños, está a distancia de \(\pi\) de 2'6676e-7: 27 veces más pequeña que la anterior. Elegir entre \(\frac{22}{7}\) y \(\frac{355}{113}\) es ya cuestión de gustos: la segunda fracción usa números más grandes pero da una aproximación mejor, por lo que que cada cual decida si necesita la precisión o no. Pero lo que queda claro es que, si nos interesa tener la mayor precisión utilizando fracciones con números más pequeños, sale más a cuenta usar \(\frac{22}{7}\) que \(\frac{157}{50}\), y \(\frac{355}{113}\) mejor que \(\frac{3927}{1250}\).

(Sí, las otras aproximaciones tienen sus ventajas: se tiene directamente una expresión decimal breve, que es lo que se usa en realidad en lugar de la expresión fraccionaria. No estoy diciendo que esté mal aproximar \(\pi\) por 3'14 o 3'1416; de hecho, no creo que las matemáticas digan nunca si algo está mal o bien. Por eso hago tanto hincapié en que todo depende de con qué criterio decimos que una aproximación es mejor o peor que otra. Si estuviera usando el criterio de mayor legibilidad sin usar fracciones, ganaría 3'14 a 22/7=3'142857142857…; aquí lo que planteo es un criterio alternativo y ver a dónde nos lleva.)

La pregunta ahora sería: teniendo una fracción \(p/q\), ¿qué fracción aproxima mejor a \(\pi\) teniendo numerador y denominador menores o iguales que \(p\) y \(q\) respectivamente? Podemos centrarnos sólo en el denominador, porque si el denominador es pequeño el numerador tendrá que serlo también. Por lo tanto: ¿con qué denominadores \(q’ < q\) se tendrá una fracción \(p’/q’\) que aproxime a \(\pi\) mejor que \(p/q\), y cuál es la mejor de todas ellas?

El primer intento va a ser a lo bruto: para cada posible denominador, vamos a probar con todos los posibles numeradores y ver qué combinación se acerca más a \(\pi\); luego, vamos a comparar la combinación que obtengamos con las que hayamos obtenido para denominadores más bajos, y ver si la cosa mejora o no. Este método empezaría haciendo:

De hecho, vamos a descartar directamente todos los numeradores que den lugar a números por debajo de 3 o por encima de 4. A partir de ahora vamos a buscar números de la forma \(3+\frac{p}{q}\), donde \(p\) irá de 0 a \(q-1\).

Realmente no hace falta comprobar tantos numeradores. Sabiendo que el 16/5=3+1/5 era la mejor aproximación con denominador 5, bastaba con probar con 3+1/6 = 19/6 y 3+2/6 = 20/6. ¿Por qué? Porque 3+3/6 ya cae por encima de 3+2/5, por lo que va a ser peor aproximación; 3+0/6 = 3+0/5 que también era una aproximación peor. En general, si sabemos que \(3+\frac{p}{q}\) es la mejor aproximación con denominador \(q\), los únicos números con denominador \(q+1\) que pueden ser candidatos a batirlo son \(3+\frac{p}{q+1}\), que caerá entre \(3+\frac{p-1}{q}\) y \(3+\frac{p}{q}\), y \(3+\frac{p+1}{q+1}\), que estará entre \(3+\frac{p}{q}\) y \(3+\frac{p+1}{q}\); cualquier otra opción estará por debajo de \(3+\frac{p-1}{q}\) o por encima de \(3+\frac{p+1}{q}\).

Podría seguir haciéndolo a mano, pero a partir de aquí se va a volver bastante tedioso. Por suerte, esto no es muy complicado de programar sabiendo Python. El código siguiente define una función que calcula, para cada denominador q, la mejor aproximación usando denominadores iguales a q, incluyendo el numerador correspondiente y la distancia a la que está de \(\pi\); el argumento que recibe la función es un denominador máximo max_denom que diga cuándo tiene que parar la función. En este caso le pedimos que calcule las mejores aproximaciones hasta \(q=1000000\).

import math
import matplotlib.pyplot as plt

def dist_a_pi(p,q):
    return abs( math.pi - (3*q+p)/q )

def dist_para_cada_denom(max_denom):
    denoms = [1]
    numers = [3]
    p1 = 0
    dists = [abs(3-math.pi)]
    for q in range(2,max_denom+1):
        q_dists = []
        p_abajo = p1
        p_arriba = p1+1
        for p1 in [p_abajo,p_arriba]:
            d = dist_a_pi(p1,q)
            q_dists.append( d )
        d = min(q_dists)
        if q_dists[0] == d:
            p1 = p_abajo
        else:
            p1 = p_arriba
        denoms.append(q)
        numer = 3*q+p1
        numers.append(numer)
        dists.append(d)
    return denoms, numers, dists

max_denom = 1000000
denoms, numers, dists = dist_para_cada_denom(max_denom)

El código posterior lo que hace es comparar las distancias obtenidas para obtener la mejor aproximación histórica: no sólo para cada denominador, sino también para todos los denominadores por debajo.

dists_mins = [dists[0]]
ultimo_min = dists_mins[0]
ultimo_denom = 1
for i in range(1,len(denoms)):
    nueva_dist = dists[i]
    nuevo_denom = denoms[i]
    if nueva_dist < ultimo_min:
        print( "Numerador", numers[i], "- Denominador", nuevo_denom, "- Distancia", nueva_dist,  )
        ultimo_min = nueva_dist
        ultimo_denom = nuevo_denom
        dists_mins.append(nueva_dist)
    else:
        dists_mins.append(ultimo_min)

El resultado que obtenemos es el que sigue:

Numerador 13 - Denominador 4 - Distancia 0.10840734641020688
Numerador 16 - Denominador 5 - Distancia 0.05840734641020706
Numerador 19 - Denominador 6 - Distancia 0.025074013076873403
Numerador 22 - Denominador 7 - Distancia 0.0012644892673496777
Numerador 179 - Denominador 57 - Distancia 0.0012417763968106676
Numerador 201 - Denominador 64 - Distancia 0.000967653589793116
Numerador 223 - Denominador 71 - Distancia 0.0007475831672580924
Numerador 245 - Denominador 78 - Distancia 0.0005670125641521473
Numerador 267 - Denominador 85 - Distancia 0.00041618300155787935
Numerador 289 - Denominador 92 - Distancia 0.0002883057637061981
Numerador 311 - Denominador 99 - Distancia 0.00017851217565167943
Numerador 333 - Denominador 106 - Distancia 8.32196275291075e-05
Numerador 355 - Denominador 113 - Distancia 2.667641894049666e-07
Numerador 52163 - Denominador 16604 - Distancia 2.662132572162079e-07
Numerador 52518 - Denominador 16717 - Distancia 2.6261055063869776e-07
Numerador 52873 - Denominador 16830 - Distancia 2.5905622225153024e-07
Numerador 53228 - Denominador 16943 - Distancia 2.555493043843171e-07
Numerador 53583 - Denominador 17056 - Distancia 2.5208885512384427e-07
Numerador 53938 - Denominador 17169 - Distancia 2.4867395653771496e-07
Numerador 54293 - Denominador 17282 - Distancia 2.4530371511843896e-07
Numerador 54648 - Denominador 17395 - Distancia 2.419772608952542e-07
Numerador 55003 - Denominador 17508 - Distancia 2.386937456577698e-07
Numerador 55358 - Denominador 17621 - Distancia 2.354523434000555e-07
Numerador 55713 - Denominador 17734 - Distancia 2.3225224943246303e-07
Numerador 56068 - Denominador 17847 - Distancia 2.2909267860526938e-07
Numerador 56423 - Denominador 17960 - Distancia 2.259728666409444e-07
Numerador 56778 - Denominador 18073 - Distancia 2.2289206702552633e-07
Numerador 57133 - Denominador 18186 - Distancia 2.1984955322906785e-07
Numerador 57488 - Denominador 18299 - Distancia 2.1684461559701163e-07
Numerador 57843 - Denominador 18412 - Distancia 2.1387656268245792e-07
Numerador 58198 - Denominador 18525 - Distancia 2.1094471902571854e-07
Numerador 58553 - Denominador 18638 - Distancia 2.080484260424953e-07
Numerador 58908 - Denominador 18751 - Distancia 2.0518704113570152e-07
Numerador 59263 - Denominador 18864 - Distancia 2.023599372513729e-07
Numerador 59618 - Denominador 18977 - Distancia 1.9956650154639988e-07
Numerador 59973 - Denominador 19090 - Distancia 1.9680613672079517e-07
Numerador 60328 - Denominador 19203 - Distancia 1.9407825835315862e-07
Numerador 60683 - Denominador 19316 - Distancia 1.91382296677034e-07
Numerador 61038 - Denominador 19429 - Distancia 1.8871769480455214e-07
Numerador 61393 - Denominador 19542 - Distancia 1.8608390828234178e-07
Numerador 61748 - Denominador 19655 - Distancia 1.8348040597970794e-07
Numerador 62103 - Denominador 19768 - Distancia 1.809066687563643e-07
Numerador 62458 - Denominador 19881 - Distancia 1.78362189018344e-07
Numerador 62813 - Denominador 19994 - Distancia 1.7584647027391043e-07
...

Hay mucha información, pero vamos a descifrarla. Vemos que, efectivamente, las fracciones 13/4, 16/5, 19/6 y 22/7 que habíamos calculado son las mejores aproximaciones para denominadores menores o iguales a 4, 5, 6 y 7 respectivamente. Lo que pasa es que la fracción 22/7 está, de golpe, mucho más cerca de \(\pi\), tan cerca que aumentar el denominador un poquito no mejora la precisión. No se encuentra una fracción más cercana a \(\pi\) hasta llegar a 179/57, que está unas pocas cienmilésimas más cerca de \(\pi\) que 22/7. Aumentar el denominador da, de vez en cuando, resultados mejores (aunque parece que hay que ir aumentándolo de 7 en 7 para ello), hasta llegar a 355/113. Igual que pasó con 22/7, esta fracción pulveriza el récord de distancia a \(\pi\) y tardará mucho en aparecer una fracción que la mejore: la fracción que mejor aproxima a \(\pi\) con el denominador más pequeño por encima de 113 es la \(\frac{52163}{16604}\).

Aumentar el denominador termina por dar mejores aproximaciones todavía, aunque vuelve a ir a saltos: la aproximación mejora aumentando el denominador de 113 en 113. Corté los resultados cuando el denominador llegó a 20000, porque a partir de ahí se pasa mucho tiempo saltando de 113 en 113. Continuando el cálculo hasta 1000000, la cosa termina

...
Numerador 102928 - Denominador 32763 - Distancia 3.3440890057079287e-09
Numerador 103283 - Denominador 32876 - Distancia 2.415684541290375e-09
Numerador 103638 - Denominador 32989 - Distancia 1.493639878447084e-09
Numerador 103993 - Denominador 33102 - Distancia 5.778906242426274e-10
Numerador 104348 - Denominador 33215 - Distancia 3.3162805834763276e-10
Numerador 208341 - Denominador 66317 - Distancia 1.2235634727630895e-10
Numerador 312689 - Denominador 99532 - Distancia 2.914335439641036e-11
Numerador 833719 - Denominador 265381 - Distancia 8.715250743307479e-12
Numerador 1146408 - Denominador 364913 - Distancia 1.6107115641261771e-12
Numerador 3126535 - Denominador 995207 - Distancia 1.1426415369442111e-12

Según esto, los saltos de 113 en 113 continúan hasta llegar al denominador 33215, donde se vuelve a encontrar una mejor aproximación más duradera, que vuelve a tardar en superarse. Se llega a superar al llegar a 66317, pero los saltos a partir de aquí se hacen más grandes.

Quedan preguntas por responder: