13 nov 2016

Números muy grandes, con todos sus dígitos, en Java

¿Cómo calcular la última cifra de un número muy grande, por ejemplo 22016? ¿Y si quisiéramos también la penúltima cifra? Es un problema típico, por ejemplo, para fomentar el razonamiento en las olimpiadas matemáticas.

Si analizamos las potencias de 2, observamos que se repite la serie de terminaciones 2  4  8  6, por lo que necesariamente tiene que ser uno de estos dígitos.
21 -> 2
22 -> 4
23 -> 8
24 -> 16
25 -> 32
26 -> 64
27 -> 128
28 -> 256
29 -> 512
210 -> 1024
211 -> 2048
212 -> 4096
213 -> 8192
214 -> 16384
215 -> 32768
216 -> 65536
217 -> 131072
218 -> 262144
219 -> 524288
220 -> 1048576

Si dividimos 2016 entre 4 terminaciones, nos da 54 grupos y de resto 0, por lo que la última cifra tiene que ser la última del grupo, es decir 6.

Si queremos la penúltima cifra tenemos que analizar los dígitos que acompañan al 6, que también son una serie, en este caso de cinco elementos, 1  5 9 3 y 7. Si ahora dividimos nuestros 54 grupos entre cinco, obtenemos 10, y de resto 4, por lo que el penúltimo número será el cuarto de la serie, es decir el 3.

Pero, ¿por qué no obtener todas las cifras del número? Pues aparentemente algo tan sencillo no es posible en muchas calculadoras a no ser que se utilice la notación científica. Pero el problema es que con esta notación no vemos todas las cifras. Si recurrimos a los lenguajes de programación el problema viene dado por los tipos para representar los enteros, los int, double, o  long, no nos permiten almacenar números tan grandes. La solución viene por utilizar clases especializadas como puede ser la clase BigInteger de Java.

El siguiente código nos muestra el resultado de 22016, aún más, muestra todas las potencias de 2, hasta 2016.

import java.math.BigInteger;

public class Potencias {

    public static void main(String[] args) {

       BigInteger resul = new BigInteger("1");

       BigInteger dos = new BigInteger("2");

       for (int i=1; i<=2016; i++){
           resul= resul.multiply(dos);
           System.out.println("2^"+ i + " -> " + resul+ "\n");
       }
    }
}

Y de esta forma, podemos ver que 22016 es un número de sólo 607 cifras:

7524389324549354450012295667238056650488661292408472865850279440061341770661038088891003609523855490537527473858068236032063038821912119420032983735773778315780422968627185582125139830259059580693966159220800634538007951025529707819651368618588002973837229854435730968342995245834129352264002058451047722604571453619205472623157541916371455764131661512732115122042085430429090324954236930736866452001076451671762299658372499364800367306988138217572983729940207496105489713305332746758395131148149101871456611571055068153665866066783899124296271513772531723497342815490725823828326183977758546404902789185536