Limitar dígitos en un número periódico en Python

publicado por: Anonymous

Hoy he empezado a usar python y me pregunto…
Si pongo un print(10/3) se limita la respuesta a

3.3333333333333335

porque óbviamente no podría escribir un número infinito… Pero, ¿hay algún modo de cambiar el número de cifras que escribe?
Por ejemplo, que en vez de escribir 16 cifras decimales escriba 20, o 3, o 45 (que pueda regular yo el número de cifras, en conclusión)

solución

El problema no es tanto con cuántos decimales quieres mostrar el número (que puedes controlarlo con cadenas de formato, como "{:.10f}".format(10/3) por ejemplo, como con qué precisión está realmente almacenado.

Por defecto los números de tipo “float” están almacenados en un formato llamado IEEE-754, el cual usa 32 o 64 bits (según la precisión sea simple o doble) para almacenar cualquier número real. Python usa la precisión doble. Naturalmente, en 64 bits que es la mayor precisión posible, se pueden representar un máximo de 2^64 números diferentes, que está muy lejos del infinito de orden Aleph1 que son los números reales. Es decir, hay infinitos números no representables en este formato.

Cuando se trabaja con números muy pequeños (del tipo 0.0000000…01) se tiene una precisión muy alta, pues los números cuya parte entera es cero se representan de una forma especial en ese formato, pudiendo llegar al orden de 2^(−1074 ), es decir, correcto hasta el decimal 324, pero a medida que los números son mayores, la precisión baja, pues el número de bits disponible para representar las cifras es constante, independientemente de dónde esté la coma.

Así, para los del tipo 1.00000…01 (que ya no tiene parte entera cero) sólo se almacena correctamente hasta el decimal 16 aproximadamente y a medida que la parte entera aumenta de tamaño, la cantidad de decimales exactos que se tiene en la parte fracción va menguando.

El resultado de 10/3 se almacena correctamente sólo hasta el decimal 15 y a partir de él ya está mal, como puedes comprobar si intentas mostrarlo con 20 decimales:

>>> print("{:.20f}".format(10/3))
3.33333333333333348136

En muchos ámbitos científicos la precisión proporcionada por el tipo float de Python (equivalente al double del C) es suficiente, ya que es habitual también en ciencia que se quiera mucha precisión al trabajar con números pequeños, y se pueda tolerar un error mayor al trabajar con números grandes, de modo que el error relativo sea constante.

No obstante, si quisieras tener control absoluto sobre la precisión, deberías dejar de usar el tipo float y pasar a usar el Decimal. En este tipo se tiene precisión arbitraria, fijada por el programador. Por desgracia es más farragoso para operar. Mira, por ejemplo, como calcular 10/3 con precisión de 30 decimales correctos:

>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 30
>>> r = Decimal(10)/Decimal(3)
>>> print(r)
3.33333333333333333333333333333

Aunque con format puedes reducir la cantidad de decimales mostrados, si tratas de aumentarlo por encima de 30 en este caso se descubre el error:

>>> print("{:.10f}".format(r))
3.3333333333
>>> print("{:.35f}".format(r))
3.33333333333333333333333333333000000

Finalmente comentar que también tienes el tipo fracción, que no intenta realizar la división sino que almacena por separado numerador y denominador, lo que evita errores de redondeo mientras trabajes con fracciones (pero aparecerán de nuevo al tratar de convertir el resultado en float)

>>> from fractions import Fraction
>>> f = Fraction(10,3)
>>> print(f)
10/3
>>> print(float(f))
3.3333333333333335
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *