Poesía Binaria

Números grandes en C usando GMP. Resolución del primer reto de #tuentiContest (Super Hard Sum)

Aquí llega mi primera aportación a las soluciones de los retos del I concurso de programación de Tuenti. La utilización de números grandes es algo que siempre me llamó la atención, y normalmente utilizo bc cuando necesito algún cálculo. Este reto se podía resolver con bash/sed/bc y, aunque varios lenguajes permiten la utilización de números de precisión arbitraria «de serie»  como python y Java, yo decidí hacerlo en C, utilizando la biblioteca GMP.

En un lenguaje como C, es normal que no podamos utilizar números de precisión arbitraria con los operadores normales (+, -, *,…), en este caso tendremos que hacer llamadas a funciones de la biblioteca para realizar las operaciones, tampoco podremos utilizar un printf() normal para mostrarlos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
*************************************************************
* @file hardsum.c
* @brief Tuenti Contest Test Phase
* Sum numbers separated by space line by line
*
* @author Gaspar Fernández <blakeyed@totaki.com>
* @version 0.0.2
* @date 12 jun 2011
*
* https://poesiabinaria.net
*
*************************************************************/


#include <stdio.h>
#include <string.h>
#include <gmp.h>

/* Huge string */
#define STRSIZE 1000

int main()
{
  char bigstr[STRSIZE];
  mpz_t tmp, sum;
  char * token;

  /* Initialize gmp numbers */
  mpz_init(tmp);
  mpz_init(sum);
 
  /* Read until EOF in stdin */
  while (fgets(bigstr, STRSIZE, stdin)!=NULL)
    {
      /* reset sum */
      mpz_set_si(sum, 0);
      token=strtok(bigstr, " \n");
      while (token!=NULL)
        {
          gmp_sscanf(token, "%Zd", &tmp); /* Extract number from token string */
          mpz_add(sum, sum, tmp);         /* Adds numbers */
          token=strtok(NULL, " \n");
        }
      gmp_printf("%Zd\n", sum);
    }

   return 0;
}

Para compilar, debemos incluir gmp:

$ gcc -o hardsum hardsum.c -lgmp

Para utilizar este tipo de variables numéricas, primero tendremos que inicializarlas con mpz_init(), otras funciones interesantes son:

GMP tiene muchísimas funciones para realizar gran cantidad de operaciones, se puede consultar la documentación aquí.

También podría interesarte....