fib <- function(n) {
a = 0
b = 1
for (i in 1:n) {
tmp = b
b = a
a = a + tmp
}
return(a)
}
print(fib(79), digits=20)
Sin embargo, si el número sobrepasa los 16 dígitos, de fib(79) en adelante, obtenemos resultados imprecisos.
Por ejemplo: fib(79) = 14472334024676220 cuando el resultado correcto es: fib(79) = 14472334024676221.
fib(77) = 5527939700884757 16 dígitosEsto es debido a que R almacena los números como números de doble precisión. Una precisión de 53 bits (16 dígitos decimales significativos aproximadamente.
+
fib(78) = 8944394323791464 16 dígitos
=
fib(79) = 14472334024676221 17 dígitos
Resolvemos el problema usando el paquete gmp (Multiple Precision Arithmetic). Específicamente la función add.bigz, con la que sumamos bigz (Large Sized Integer Values) números enteros muy grandes.
install.packages("gmp")
require(gmp)
fib <- function(n) {
a = 0
b = 1
for (i in 1:n) {
tmp = b
b = a
a = add.bigz(a, tmp) # gmp function
}
return(a)
}
fib(79)
Así calculamos correctamente números de más de 16 dígitos. He comprobado los resultados para números mucho más largos fib(25000), 5225 dígitos, y los resultados parecen ser precisos hasta el último dígito.R al igual que otros lenguajes tiene limitaciones internas. Aunque en la práctica es poco probable que topemos con ellas, es útil tenerlas presentes y, si es posible, ser capaces de sobrepasarlas. En este caso, ya sabemos como sortear la limitación en la precisión de los cálculos más allá de los 16 dígitos con el paquete gmp.
Referencias:
Double-precision floating-point formatEntradas relacionadas:
R Accuracy
?double en la consola de R
Sucesión de Fibonacci en Excel y VBA
No hay comentarios:
Publicar un comentario