Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: DickGumshoe en 6 Julio 2012, 16:17 pm



Título: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 16:17 pm
Hola.

Gracias a Avesudra, ayer pude configurar la librería GMP en Codeblocks. Llevo toda la mañana intentando calcular la suma de todos los dígitos del resultado de hacer 21000. Lo que hago es esto:

Código
  1. #include <stdio.h>
  2. #include <gmp.h>
  3.  
  4. unsigned long int suma=0, i=0;
  5. //Lo pongo como variable global porque si lo meto en main() me dice "Suma dígitos.exe dejó de funcionar. Windows está buscando una solución"
  6.  
  7. int main()
  8. {
  9.  
  10.    mpz_t num, resultado, mod; //Variables
  11.  
  12.    mpz_set_ui(num, 2); //Inicializo num a 2
  13.    mpz_init(resultado); //resultado = 0
  14.    mpz_init(mod); //mod=0
  15.  
  16.    mpz_pow_ui(resultado, num, 1000); // 2^1000
  17.    gmp_printf("Resultado: %Zd\n\n", resultado); //Imprimo 2^1000, y el resultado es correcto
  18.  
  19.    while(mpz_cmp_ui(resultado, 0) > 0)
  20.    {//BUCLE INFINITO
  21.        suma += mpz_mod_ui(mod, resultado, 10); //suma = suma + el resto de dividir resultado entre 10
  22.        mpz_set_ui(resultado, mpz_cdiv_ui(resultado, 10)); //Dividimos resultado entre 10
  23.        printf("%d\n", suma); //Además de que el bucle es infinito, he comprobado que la suma la hace mal.
  24.  
  25.    }
  26.  
  27.  
  28.    printf("Suma: %d", suma);
  29.  
  30.    mpz_clear(resultado); //Liberamos memoria
  31.    mpz_clear(num);
  32.    mpz_clear(mod);
  33.  
  34.    return 0;
  35. }
  36.  

21000 lo hace bien, pero se queda en el while(), no sé por qué...

Mi idea era inicializar suma a 0, hallar el resto de dividir 21000 entre 10, y sumárselo, y así hasta que "resultado = 0", puesto que si llega a 0 significa que ya hemos sumado todas sus cifras.

¿Alguien tiene una idea de qué hago mal?

Muchas gracias.

Saludos.



Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 16:21 pm
Emmm... me parece que se te ha olvidado inicializar mpz_t num , no sé si ese es el único error , lo he mirado así por encima.

EDITO: Tienes que inicializar las variables antes de asignarles cualquier otro tipo de datos así que te falta:
Código:
mpz_init(num)
Oye una cosa¿ la condición del while en pseudocódigo  cual es?


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 16:28 pm
Muchas gracias por responder.

Lo he inicializado, solo que dándole otro valor distinto de 0. Así:

Código
  1. mpz_set_ui(num, 2); //Inicializo num a 2

Además, debe estar bien, porque esa variable la utilizo para hacer 21000 y dicho resultado me da bien.

Saludos.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 16:33 pm
Ah si perdona es que no había visto las funciones de inicialización y asignación combinadas en la documentación , de todas maneras es así :
Código
  1. mpz_init_set_ui (num, 2);
En cuanto al bucle que condición es la que quieres poner, que resultado sea igual a 0?
entonces sería así while(mpz_cmp_ui(resultado,0)!=0)


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 16:37 pm
Muchas gracias por corregir esa función, con la que había puesto yo tenía que crear la variable resultado también porque sino me daba error.

Sí, lo que quiero poner en el while() es que mientras resultado > 0, haga todo eso.

Saludos.

EDITO: También puse esa condición y no salía...

EDITO 2: Creo que el error no es la condición, sino lo de dentro, ya que he probado a poner:

Código
  1. while(mpz_cmp_ui(resultado, 0) !=0)
  2.    {//BUCLE INFINITO
  3.        suma += mpz_mod_ui(mod, resultado, 10); //suma = suma + el resto de dividir resultado entre 10
  4.        mpz_set_ui(resultado, mpz_cdiv_ui(resultado, 10)); //Dividimos resultado entre 10
  5.        gmp_printf("%Zd\n", resultado); //Además de que el bucle es infinito, he comprobado que la suma la hace mal.
  6.  
  7.    }

Y no da nunca resultado/10...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 16:42 pm
Ya he visto que no me funciona ...Voy a ver si te lo hago desde 0 , entonces recapitulamos , tenemos que sumar todos los dígitos de 21000¿no?


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 16:44 pm
Sí, sería sumando los dígitos de 21000, pero ahora me he quedado con la curiosidad de por qué sale mal lo que he hecho... Seguiré probando, a ver si saco algo...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 16:50 pm
Estoy mirando el código y ten mucho cuidado con las funciones que utilizas , mira la función esta lo que retorna:
Código:
mpz_cdiv_ui(resultado, 10)
No retorna el número dividido , sino el resto de la división...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 16:59 pm
Ya está listo dame un momento y te publico lo que está mal...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 17:13 pm
Pues mira te explico lo que tenías mal:
  • Primero de todo la función mpz_set_ui(num,2); no inicializaba resultado , era mpz_init_set_ui(num,2)
  • Segundo la función mpz_cdiv_ui(resultado, 10); no retornaba el número dividido si no el resto de la división
  • Tercero el especificador de conversion para un tipo unsigned long int es %lu
Y creo que no se me olvida más nada , mmm ah si el codigo ! ¿Que valor daba la suma?
Código
  1. #include <stdio.h>
  2. #include <gmp.h>
  3.  
  4. unsigned long int suma=0, i=0;
  5. //Lo pongo como variable global porque si lo meto en main() me dice "Suma dígitos.exe dejó de funcionar. Windows está buscando una solución"
  6.  
  7. int main()
  8. {
  9.  
  10.    mpz_t num, resultado, mod; //Variables
  11.    mpz_inits(resultado,mod,NULL);//Resultado y mod inicializado a 0;
  12.    mpz_init_set_ui(num, 2); //Inicializo num a 2
  13.    mpz_pow_ui(resultado, num, 1000); // 2^1000
  14.    gmp_printf("Resultado: %Zd\n\n", resultado); //Imprimo 2^1000, y el resultado es correcto
  15.  
  16.    while(mpz_cmp_ui(resultado, 0) > 0)
  17.    {//BUCLE NO INFINITO
  18.        suma += mpz_mod_ui(mod, resultado, 10); //suma = suma + el resto de dividir resultado entre 10
  19.        //printf("SUMA :%d \n", suma); Probando la suma...
  20.        mpz_tdiv_q_ui(resultado,resultado, 10);//Realizamos una division entre 10 y no redondeamos, lo que sobra lo truncamos.
  21.        //mpz_set_ui(resultado, mpz_cdiv_ui(resultado, 10)); Esto está mal , la función mpz_cdiv_ui devuelve el resto de la division!!
  22.        gmp_printf("Resultado dividiendo: %Zd\n\n", resultado);
  23.        printf("%lu\n", suma); //Además de que el bucle es infinito, he comprobado que la suma la hace mal.
  24.  
  25.    }
  26.    printf("Suma: %lu\n", suma);
  27.    mpz_clears(resultado,num,mod,NULL); //Liberamos memoria
  28.    getchar();
  29.    return 0;
  30. }
  31.  
¡Un saludo!


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 17:24 pm
¡Muchas gracias! Creía que era esa función la de dividir...

La suma no da... Así que he puesto esto:

 
Código
  1. while(mpz_cmp_ui(resultado, 0) >0)
  2.    {//BUCLE INFINITO
  3.        suma += mpz_mod_ui(mod, resultado, 10); //suma = suma + el resto de dividir resultado entre 10
  4.        mpz_tdiv_q_ui(resultado, resultado, 10); //Dividimos resultado entre 10
  5.        printf("%d\n", suma); //Además de que el bucle es infinito, he comprobado que la suma la hace mal.
  6.        getchar();
  7.  
  8.    }

Para ver qué pasaba, y los primeros números los suma bien, pero a partir de 565 sale un número muy grande, números negativos, etc. (no sé por qué salen negativos, cuando "suma" es unsigned long int...)...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 17:31 pm
Pues es que unsigned long int , es de 4 bytes de longitud 4*8= 32 bits , o sea que solo puede contener hasta 232=4,294,967,295 , pero eso no tiene nada que ver porque esas cifras no suman tal cantidad de numeros, así que no sé , cuanto debe de dar la suma entonces?


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 17:32 pm
El problema es de una página muy conocida de retos de programación, por lo que buscando en Internet acabo de ver que da 1366. No sé si será el resultado correcto...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 17:39 pm
Eso me dá a mí , a ti ¿cuanto te dá? ¿Que página es?


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 17:42 pm
Qué raro... A mí me da 1620828886. La página es Project Euler.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 17:43 pm
A ver vamos a hacer una cosa , vamos a guardarla en la variable suma pero está ahora vá a ser de tipo mpz_t ahora te paso el codigo a ver que tal , pero me parece rarísimo.Toma aquí tienes , ahora lo que he hecho es que la variable suma es de tipo mpz_t
Código
  1. #include <stdio.h>
  2. #include <gmp.h>
  3.  
  4.  
  5. int main()
  6. {
  7.    mpz_t num, resultado, mod,suma; //Variables
  8.    mpz_inits(resultado,mod,suma,NULL);//Resultado suma y mod inicializado a 0;
  9.    mpz_init_set_ui(num, 2); //Inicializo num a 2
  10.    mpz_pow_ui(resultado, num, 1000); // 2^1000
  11.    gmp_printf("Resultado: %Zd\n\n", resultado); //Imprimo 2^1000, y el resultado es correcto
  12.  
  13.    while(mpz_cmp_ui(resultado, 0) > 0)
  14.    {//BUCLE NO INFINITO
  15.         mpz_add_ui(suma,suma,mpz_mod_ui(mod, resultado, 10)); //suma = suma + el resto de dividir resultado entre 10
  16.        //printf("SUMA :%d \n", suma); Probando la suma...
  17.        mpz_tdiv_q_ui(resultado,resultado, 10);//Realizamos una division entre 10 y no redondeamos, lo que sobra lo truncamos.
  18.        //mpz_set_ui(resultado, mpz_cdiv_ui(resultado, 10)); Esto está mal , la función mpz_cdiv_ui devuelve el resto de la division!!
  19.        gmp_printf("Suma: %Zd\n\n", suma); //Además de que el bucle es infinito, he comprobado que la suma la hace mal.
  20.        //getchar();
  21.  
  22.    }
  23.    gmp_printf("Suma final: %Zd\n\n", suma);
  24.    mpz_clears(resultado,num,mod,suma,NULL); //Liberamos memoria
  25.    getchar();
  26.    return 0;
  27. }
  28.  
Vamos a ver una cosa compila este código y dime lo que te sale también...
Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.    printf("El tamano de un unsigned long int en tu maquina es de: %d bytes",sizeof(unsigned long int));
  6.    getchar();
  7.    return 0;
  8. }
  9.  


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 17:51 pm
Tanto en tu código como en uno que he hecho yo (que ha resultado ser igual que el tuyo), me da 43123298370...  :(


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 17:59 pm
Me sale 4 bytes.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 18:21 pm
Pues ni idea la verdad , igual es que mis librerias como las compile para mi ordenador no sirven para el tuyo...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 18:23 pm
Yo creo que sí sirven, porque sino me daría error al compilar, o me daría mal 21000... Veré que puedo hacer.

Gracias por haberme ayudado!

Saludos.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 18:26 pm
No sé yo eh , sobre que Windows estás compilando x64 o x32 ?  Yo compilé mis librerias desde x64 a ver si no sirven , compila las tuyas.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 18:28 pm
Desde Windows 7 x64


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 18:41 pm
Yo que tú compilaba las librerías , con el tutorial ese que posteé.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 18:50 pm
¡Mira lo que me ha pasado ahora!  :-(

Para probar si me hacía la división bien, he puesto:

Código
  1. while(mpz_cmp_ui(resultado, 0) >0)
  2.    {//BUCLE INFINITO
  3.        suma += mpz_mod_ui(mod, resultado, 10); //suma = suma + el resto de dividir resultado entre 10
  4.        mpz_tdiv_q_ui(resultado, resultado, 10); //Dividimos resultado entre 10
  5.        gmp_printf("Resultado: %Zd\n\n", resultado);
  6.        getchar();
  7.    }

(el getchar() para pausar y poder ver que todo va bien)

Y con eso me ha ido haciendo esto:

Código:
Resultado: 107150860718626732094842504906000181056140481170553360744375038837035105112493612
24931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230
98542107460506237114187795418215304647498358194126739876755916554394607706291457119647768654
2167660429831652624386837205668069376

Resultado: 107150860718626732094842504906000181056140481170553360744375038837035105112493612
24931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230
98542107460506237114187795418215304647498358194126739876755916554394607706291457119647768654
216766042983165262438683720566806937


Resultado: 107150860718626732094842504906000181056140481170553360744375038837035105112493612
24931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230
98542107460506237114187795418215304647498358194126739876755916554394607706291457119647768654
21676604298316526243868372056680693


Resultado: GNU MP: Cannot reallocate memory (old_size=291 new_size=300)

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

No creo que sea por lo de la librería (ya que las operaciones me las hace bien, o hasta cierto punto), pero igualmente voy a intentar compilarla, por si acaso...

EDITO: Ya he compilado la librería por mí mismo y sigue saliendo mal... 

Creo que lo mejor será dejarlo, porque si en un ordenador sale y en otro no...  :-(


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 20:03 pm
Pues es muy raro , mira intenta inicializar la variable resultado así , mpz_init2(resultado,10000000);


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 20:06 pm
Tampoco va... Sigo probando cosas y leyendo un poco el manual, pero dudo que venga algo allí, porque si el programa está bien...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 20:17 pm
Voy a pasarte el exe , si no funciona , está claro que no son las librerías y que tu SO es el problema supongo.
Aquí lo tienes: http://www.mediafire.com/?fpt5yyatz64yz47


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 20:22 pm
Siento si te he molestado ya mucho, pero... No me deja descargarlo  :(


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 20:27 pm
Que no molestas hombre :) , será el antivirus , prueba con este:
http://www.mediafire.com/?mbw2v6ywhndpstv


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 20:31 pm
Me dice:

"El programa no puede iniciarse porque falta libgcc_s_dw2-1.dll en el equipo. Intente reinstalar el programa para corregir este problema."  :huh:


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 20:37 pm
No sabes como odio los problemas con las .dll's  :xD prueba con este que lleva la dll:
http://www.mediafire.com/?kld0s4vbqd22e6e


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 20:40 pm
Muchas gracias. No da el resultado correcto... Por lo que no debería ser del código, y me he llevado toda la tarde mirándolo xD


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 23:49 pm
Lo único que se me ocurre es que intentes compilar una versión anterior de la librería. A ver si va a ser un bug...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 6 Julio 2012, 23:51 pm
Si fuera un bug a ti también te tendría que salir mal, supongo...


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 6 Julio 2012, 23:57 pm
¿Y si depende del ordenador o algo de eso? Es que no te puedo orientar más , hay muy poca información al respecto y yo no sé mucho ... De todas maneras prueba con esta que está precompilada http://www.cs.nyu.edu/exact/core/gmp/gmp-static-mingw-4.1.tar.gz , tienes que hacer lo mismo que con la que instalaste , pero quita la que te pasé yo antes!

EDITADO: Es posible que si intentas compilar tu  código modificado por mi con esa librería , obtengas errores refiriendose a la funcion mpz_inits y mpz_clears supongo que en antiguas versiones no estaba implementada.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 7 Julio 2012, 00:05 am
¡Muchísimas gracias, Avesudra! Me has ayudado muchísimo! Debe ser un bug como bien has dicho ya, porque ahora sí me funciona!!

Reitero, muchísimas gracias!!

Saludos.


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 7 Julio 2012, 00:11 am
¡Muchas de nadas! Debe de ser un bug que dependa del tipo de hardware del ordenador(cpu , cantidad de ram...) a lo mejor, es que no tengo ni idea la verdad, porque si mis librerías estuviesen mal compiladas no me saldría a mí tampoco... ¡Pues bueno problema solucionado! ¡A programar tranquilamente!

¡Un saludo crack!


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: DickGumshoe en 7 Julio 2012, 00:15 am
Eso sí, no me gustaría que le pasara a otro, porque yo mismo he vivido este sufrimiento que se tiene cuando ves que una cosa está bien y no sale lo que debe salir.

¿Ves bien que intente contactar a los creadores de la librería para informar del bug?


Título: Re: ¿Uso mal las funciones de la librería GMP?
Publicado por: avesudra en 7 Julio 2012, 00:18 am
Eso te iba a decir , no estaría mal , pero hay una especie de documentación para reportarlo mira http://gmplib.org/manual/Reporting-Bugs.html , una cosa sería mejor que comentasemos esto ya por privado porque el tema principal del hilo se ha zanjado.