Euler # 26, cómo convertir número racional a la cadena con mayor precisión?
-
19-09-2019 - |
Pregunta
Quiero conseguir 1/7
con una mejor precisión, pero quedó truncado. ¿Cómo puedo obtener una mejor precisión al convertir un número racional?
>>> str(1.0/7)[:50]
'0.142857142857'
Solución
Python tiene una biblioteca incorporada para los cálculos de precisión arbitraria: Decimal. Por ejemplo:
>>>from decimal import Decimal, getcontext
>>>getcontext().prec = 50
>>>x = Decimal(1)/Decimal(7)
>>>x
Decimal('0.14285714285714285714285714285714285714285714285714')
>>>str(x)
'0.14285714285714285714285714285714285714285714285714'
Mire la Python decimal documentación para más detalles. Puede cambiar la precisión a ser tan alto como sea necesario.
Otros consejos
Se podría multiplicar el numerador por un gran 10 ^ N y se pega con números enteros de precisión arbitraria.
editar
Me refiero a:
> def digits(a,b,n=50): return a*10**n/b
.
> digits(1,7)
14285714285714285714285714285714285714285714285714L
enteros de Python son de precisión arbitraria. flotadores de Python son de precisión no arbitraria. (Habría que utilizar decimal, como otra respuesta ha señalado)
El uso de Perl (porque no puedo escribir Python; -):
use strict; use warnings;
use integer;
my $x = 1;
my $y = 7;
for (1 .. 50) {
$x *= 10 if $x < $y;
my $q = $x / $y;
$x -= $q * $y;
print $q;
}
print "\n";
14285714285714285714285714285714285714285714285714
Como se puede comprobar con la mano, la repetición de dígitos. Impresión mediante "%.50f"
le dará la ilusión de mayor precisión.
gmpy :
>>> import gmpy
>>> thefraction = gmpy.mpq(1, 7)
>>> hiprecfloat = gmpy.mpf(thefraction, 256)
>>> hiprecfloat.digits(10, 50, -10, 10)
'0.14285714285714285714285714285714285714285714285714'
>>>
No se puede hacer con flotadores normales - que simplemente no tienen suficiente precisión para 50 dígitos! Me imagino que hay una manera de hacerlo (en 2.6 o mejor) con fractions.Fraction
, pero no estoy familiarizado con alguna forma de formatearlo otro modo que como '1/7'
(no muy útil en su caso -).