Alters

BigInteger - Funciones básicas: Creación de BigInteger

Buenas!

Vamos a empezar a explicar el desarrollo de la arquitectura para grandes números "BigInteger".

En esta ocasión, nos toca explicar la función de creación de BigInteger.

  • ¿No es la entrada que buscabas? Entra en el índice
  • ¿Buscas el código fuente? Aquí lo tienes


La creación de un BigInteger se basa en los datos procedentes de una cadena de caracteres (podríamos llamarla "String", pero ese concepto en C es un poco... confuso, ya que como tal, es un puntero a caracteres - char*).

Los datos asignados a números se almacenan en un array de datos int con un tamaño predefinido (por defecto, de 4096 posiciones).

Antes de seguir, comentar la que quizá es la mayor particularidad del sistema, y es que los datos se almacenan en el orden inverso al "lógico". Es decir, el valor de más a la  izquierda en BigInteger es el dato con menor peso en el número; y además, irónicamente, un cero a la izquierda en BigInteger tiene importancia! (ya que estamos multiplicando el número por diez).

Esta decisión se basa en aportar un sistema rápido de crecimiento: utilizando esta solución, si el número creciera, basta con ocupar la siguiente posición del array; en caso contrario, habría que desplazar una posición todos los datos para posteriormente añadir el nuevo dato en la posición [0] del array.

Bien, una vez comentada esta particularidad, vamos con la creación en si.

Como se explicaba al inicio, partimos de un array de caracteres, que contiene el valor absouluto del número a crear, y lo vamos convirtiendo a datos numéricos y almacenando en nuestro array (BigInteger.n).

Para ahorrar espacio, también se debe pasar un puntero al BigInteger que queremos crear, ya que de esta manera la función es capaz de limpiar toda la memoria consumida, haciendo que el consumo de memoria sea menor (ya veréis que todas las funciones se basan en punteros con el mismo fin).

Así pues, se siguen las siguientes operaciones

  • Crear un BigInteger temporal
  • Limpiar el BigInteger temporal (esto es, dejar todas las posiciones de BigInteger.n con valor 0)
  • Recorremos de manera inversa el puntero de texto, y por cada posición
    • Convertimos el carácter en un valor numérico usando su valor (ASCII - 48)
    • Si su valor no es válido (es decir, no está entre 0 y 9) se detiene la ejecución
  • Indicamos en BigInteger.count el número de datos informados
  • Si nos han indicado un signo negativo (parámetro de entrada), modificamos el último valor de BigInteger.n para cambiar su signo.
  • Copiamos el BigInteger temporal al puntero enviado
  • Borramos el BigInteger temporal

En forma gráfica, el flujo para crear el BigInteger "-123456" sería el siguiente:



Como veis, el punto más complejo es el trabajar con los datos en formato "inverso".

Y hasta aquí puedo leer, espero que os despierte la curiosidad...

¡Nos vemos!

No hay comentarios:

Publicar un comentario