Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 25 Septiembre 2014, 20:05 pm



Título: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 25 Septiembre 2014, 20:05 pm
Hola a todos.

Código
  1. #include <stdio.h>
  2.  
  3. #define MAX 10000
  4. void numerosPerfectos();
  5.  
  6. int main(void){
  7.  
  8. numerosPerfectos();
  9.  
  10. return 0;
  11. }
  12.  
  13. void numerosPerfectos(){
  14. int acumulador=0, i, j=1;
  15.  
  16. printf("\n\n N%cmeros perfectos...: ", 163);
  17.  
  18. for(i=1; i<MAX; i++){
  19. acumulador = 0;
  20. for(j=1; j<i; j++){
  21. if(i % j == 0){
  22. acumulador += j;
  23. }
  24. }
  25. if(i == acumulador){
  26. printf(" %d ", i);
  27. }
  28. }
  29. }

El inconveniente es que si pongo #define MAX 10000 el resultado lo muestra en un periodo de tiempo aceptable, pero si deseo saber del 1 al 100000 muestra ==> 6- 28 – 496 – 8128 y de aquí en más tarda en términos de computación una eternidad (para terminar el programa).-
La consulta es, ¿sabe alguien otra manera de hacerlo?, mi computadora si bien es un poco vieja (2gb de ram) me parecería que tendría que mostrarlo al instante, pero no es así.-

Desde ya muchas gracias.-
   
Saludos.
Daniel   


Título: Re: Números perfectos (lenguaje C)
Publicado por: ivancea96 en 25 Septiembre 2014, 21:00 pm
*La capacidad de la RAM en este caso no es especialmente relevante.

En cuanto al tema, no necesitas dar X iteraciones para un número X. Basta con poner de tope la raíz cuadrada del número.

Una vez encontrados los divisores inferiores a la raiz cuadrada, los divisores superiores son, siendo el divisor inferior 'N', X/N.

Dado que K*N = X, una vez sacamos un divisor, por ejemplo N, ya tenemos también K.

En caso de que X sea un cuadrado perfecto, X/N==N, por lo que no habría que sumarlo.

En definitiva, esto no es un problema de C++, esto es un problema de algoritmia y matemáticas, quizás fuera más correcto colocarlo en el Foro Libre o en Programación General.


Título: Re: Números perfectos (lenguaje C)
Publicado por: engel lex en 25 Septiembre 2014, 21:11 pm
rayos ivancea96 te me adelantaste! estaba preparando la respuesta jejeje igual allí voy (en gran parte para repetirte)


lo importante aquí no es la ram, ya que el programa solo usa 3 int (en total 12bytes) + el programa en si que dudo que llegue a 100kb... esto no llegará a 1mb de ram...

el problema aquí es el tiempo de procesamiento, es decir la velocidad del procesador contra la cantidad de operaciones hechas, por la estructura de tu programa el hace x! operaciones donde x es MAX

es decir cada paso la cantidad de cálculos aumenta brutalmente

por otro lado algo que tarda es el printf, es preferible que guardes en un array y luego imprimas, es más rápido guardar 4bytes en la ram que iniciar todo un proceso para imprimir en pantalla

realmente no estoy claro sobre tu proceso de los "números perfectos" pero intenta buscar alguna formula que te resuma el ciclo

-------agrego--------

estuve investigando y según Euclides los números perfectos se basan en esta formula
(http://upload.wikimedia.org/math/0/9/b/09b430032441a41d53299656e04741bd.png)
donde "n" es un numero primo... esa es tu solucion
ej:
Citar
n = 2:   21 × (22 – 1) = 6
n = 3:   22 × (23 – 1) = 28
n = 5:   24 × (25 – 1) = 496
n = 7:   26 × (27 – 1) = 8128

esa forma debe ser infinitamente más ligera para el procesador especialmente si lo haces con desplazamiento de bits, porque son potencias de 2


Título: Re: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 25 Septiembre 2014, 21:21 pm
Hola ivancea99.
Citar
Te agradezco el aporte, si en algún momento te encuentras con tiempo libre te agradecería si pones un poco de código, con mis 62 años me cuesta recordar raíz cuadradas y demás, sé que es algo  que indefectiblemente voy a tener que estudiar si quiero aprender a programar, pero en este momento estoy en el tema funciones en c y es lo que me pide el libro hacer.-
   
Mientras estaba tratando de solicitar ayuda y agradecer a ivancea99 me aparece el cartelito rojo advirtiendo  que hubo otra respuesta al tema…
engel lex creo que estas en lo cierto “si lo haces con desplazamiento de bits” lo voy a intentar, aunque a fuerza de ser prejuicioso no creo que lo logre por mi mismo    
  
Saludos.
Daniel


Título: Re: Números perfectos (lenguaje C)
Publicado por: Shout en 25 Septiembre 2014, 22:07 pm
Hola ivancea99.     
Mientras estaba tratando de solicitar ayuda y agradecer a ivancea99 me aparece el cartelito rojo advirtiendo  que hubo otra respuesta al tema…
engel lex creo que estas en lo cierto “si lo haces con desplazamiento de bits” lo voy a intentar, aunque a fuerza de ser prejuicioso no creo que lo logre por mi mismo   
   
Saludos.
Daniel
Hazlo multiplicando, seguramente el compilador lo optimice a bitshifts.


Título: Re: Números perfectos (lenguaje C)
Publicado por: engel lex en 25 Septiembre 2014, 22:20 pm
es muy simple, resumes toda la operacion a una sola linea... pero ahora tienes un problema diferente pero más simple, buscar numeros primos jejeje la operacion de numeros primos se ha hablado mucho en el foro y hay soluciones rapidas y creativas... eso si, descubrirás el uso de unsigned y long porque estás usando numero MUY grandes...

me diste algo que investigar, estuve viendo la progesion completa (sin importar si eran primos o no) en binario y son muy simple en ese aspecto... pero me da un error que no descubro la razón...

alquien me da ayuda?
Código:
2 = resultado:	0000000000000000000000000000000000000000000000000000000000000110
3 = resultado: 0000000000000000000000000000000000000000000000000000000000011100
4 = resultado: 0000000000000000000000000000000000000000000000000000000001111000
5 = resultado: 0000000000000000000000000000000000000000000000000000000111110000
6 = resultado: 0000000000000000000000000000000000000000000000000000011111100000
7 = resultado: 0000000000000000000000000000000000000000000000000001111111000000
8 = resultado: 0000000000000000000000000000000000000000000000000111111110000000
9 = resultado: 0000000000000000000000000000000000000000000000011111111100000000
10 = resultado: 0000000000000000000000000000000000000000000001111111111000000000
11 = resultado: 0000000000000000000000000000000000000000000111111111110000000000
12 = resultado: 0000000000000000000000000000000000000000011111111111100000000000
13 = resultado: 0000000000000000000000000000000000000001111111111111000000000000
14 = resultado: 0000000000000000000000000000000000000111111111111110000000000000
15 = resultado: 0000000000000000000000000000000000011111111111111100000000000000
16 = resultado: 0000000000000000000000000000000001111111111111111000000000000000
17 = resultado: 0000000000000000000000000000000111111111111111110000000000000000
18 = resultado: 0000000000000000000000000000011111111111111111100000000000000000
19 = resultado: 0000000000000000000000000001111111111111111111000000000000000000
20 = resultado: 0000000000000000000000000111111111111111111110000000000000000000
21 = resultado: 0000000000000000000000011111111111111111111100000000000000000000
22 = resultado: 0000000000000000000001111111111111111111111000000000000000000000
23 = resultado: 0000000000000000000111111111111111111111110000000000000000000000
24 = resultado: 0000000000000000011111111111111111111111100000000000000000000000
25 = resultado: 0000000000000001111111111111111111111111000000000000000000000000
26 = resultado: 0000000000000111111111111111111111111110000000000000000000000000
27 = resultado: 0000000000011111111111111111111111111100000000000000000000000000
28 = resultado: 0000000001111111111111111111111111111000000000000000000000000000
29 = resultado: 0000000111111111111111111111111111110000000000000000000000000000
30 = resultado: 0000011111111111111111111111111111100000000000000000000000000000
31 = resultado: 0101111111111111111111111111111111000000000000000000000000000000
32 = resultado: 0000000000000000000000000000000000000000000000000000000000000000

en el 31 aún y cuando son solo desplazamientos se salta un 1 en el penultimo bit y 32 el ultimo en lugar de desbordarse, se limpió (no pongo el código por razones del post)

Hazlo multiplicando, seguramente el compilador lo optimice a bitshifts.
cierto! :P igual no son operaciones tan pesadas


Título: Re: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 25 Septiembre 2014, 22:47 pm
Considerando mi nivel de programación y atento a lo que me proponen me despido por unos 6 meses :rolleyes: :huh: ;D, espero que la pasen muy bien y un gran abrazo, cuando tenga el programa completado y funcionando regreso.-   

Saludos.
Daniel   


Título: Re: Números perfectos (lenguaje C)
Publicado por: engel lex en 25 Septiembre 2014, 23:04 pm
Considerando mi nivel de programación y atento a lo que me proponen me despido por unos 6 meses :rolleyes: :huh: ;D, espero que la pasen muy bien y un gran abrazo, cuando tenga el programa completado y funcionando regreso.-   

Saludos.
Daniel   


jejeje no seas dramatico! tranquilo que pensandolo eso sale, como dice Shout puedes hacerlo con multiplicaciones... o tomando su palabra, puedes incluso hacerlo con la libreria "<cmath>" y usando pow como en estos ejemplos (http://www.cplusplus.com/reference/cmath/pow/)


Título: Re: Números perfectos (lenguaje C)
Publicado por: Blaster en 25 Septiembre 2014, 23:36 pm
La consulta es, ¿sabe alguien otra manera de hacerlo?, mi computadora si bien es un poco vieja (2gb de ram) me parecería que tendría que mostrarlo al instante, pero no es así.-

Aquí tienes un código bastante interesante, que a mi parecer es bastante rápido :

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5.  
  6. char bits[65536];
  7.  
  8. typedef unsigned long ulong;
  9. ulong primes[7000], n_primes;
  10.  
  11. typedef struct
  12. {
  13.    ulong p, e;
  14. } prime_factor;
  15.  
  16. void sieve(void)
  17. {
  18.    int i, j;
  19.    memset(bits, 1, 65536);
  20.    bits[0] = bits[1] = 0;
  21.    for (i = 0; i < 256; i++)
  22.        if (bits[i])
  23.            for (j = i * i; j < 65536; j += i)
  24.                bits[j] = 0;
  25.    for (i = j = 0; i < 65536; i++)
  26.        if (bits[i]) primes[j++] = i;
  27.  
  28.    n_primes = j;
  29. }
  30.  
  31. int get_prime_factors(ulong n, prime_factor *lst)
  32. {
  33.    ulong i, e, p;
  34.    int len = 0;
  35.  
  36.    for (i = 0; i < n_primes; i++)
  37.    {
  38.        p = primes[i];
  39.        if (p * p > n) break;
  40.        for (e = 0; !(n % p); n /= p, e++);
  41.        if (e)
  42.        {
  43.            lst[len].p = p;
  44.            lst[len++].e = e;
  45.        }
  46.    }
  47.    return n == 1 ? len : (lst[len].p = n, lst[len].e = 1, ++len);
  48. }
  49.  
  50. int ulong_cmp(const void *a, const void *b)
  51. {
  52.    return *(const ulong*)a < *(const ulong*)b ? -1 : *(const ulong*)a > *(const ulong*)b;
  53. }
  54.  
  55. int get_factors(ulong n, ulong *lst)
  56. {
  57.    int n_f, len, len2, i, j, k, p;
  58.    prime_factor f[100];
  59.  
  60.    n_f = get_prime_factors(n, f);
  61.  
  62.    len2 = len = lst[0] = 1;
  63.    for (i = 0; i < n_f; i++, len2 = len)
  64.        for (j = 0, p = f[i].p; j < f[i].e; j++, p *= f[i].p)
  65.            for (k = 0; k < len2; k++)
  66.                lst[len++] = lst[k] * p;
  67.  
  68.    qsort(lst, len, sizeof(ulong), ulong_cmp);
  69.    return len;
  70. }
  71.  
  72. int main(void)
  73. {
  74.    int j;
  75.    ulong fac[10000], n, sum;
  76.  
  77.    sieve();
  78.  
  79.    for (n = 2; n < 33550337; n++)
  80.    {
  81.        j = get_factors(n, fac) - 1;
  82.        for (sum = 0; j && sum <= n; sum += fac[--j]);
  83.           if (sum == n)
  84.              printf("%lu\n", n);
  85.    }
  86.    return 0;
  87. }
  88.  

Fuente : http://rosettacode.org/wiki/Factors_of_an_integer#Prime_factoring (http://rosettacode.org/wiki/Factors_of_an_integer#Prime_factoring)

Solo le hice una pequeña modificación en el main para adaptarlo a tu propósito

Un Saludo


Título: Re: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 26 Septiembre 2014, 15:46 pm
Hola Blaster.
Muchas gracias por tú aporte, en realidad es mucho más rápido que el que yo postee, por lo menos los primeros cuatros aparecen al instante pero el quinto no me aparece nunca, de cualquier manera voy a intentar implementar lo de engel lex, me parece que de esa manera va a funcionar muy bien.-   

Citar
n = 2:   21 × (22 – 1) = 6
n = 3:   22 × (23 – 1) = 28
n = 5:   24 × (25 – 1) = 496
n = 7:   26 × (27 – 1) = 8128

Mil disculpas si se me pasó por alto agradecer a alguien y les pongo esta página que está relacionada y me causo mucha gracia.-

http://curiotecnology.blogspot.com.ar/2012/05/los-5-numeros-perfectos-java.html


Saludos.
Daniel   


Título: Re: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 27 Septiembre 2014, 16:48 pm
Hola, buen día.-
engel lex realmente una genialidad lo tuyo, me allano mucho el camino y gracias a todos los que propusieron algo parecido y al resto.-

Código
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4.  
  5. void primo(void);
  6. void perfecto(int num);
  7.  
  8. int main(void){
  9.  
  10. primo();
  11.  
  12. printf("\n\n");
  13. return 0;
  14. }
  15.  
  16. void primo(void){
  17. int num,j, a=0;
  18. for(num=0; num<=13; num++){
  19. for(j=1; j<=num; j++){
  20. if(num%j==0){
  21. a++;
  22. }
  23. }
  24. if(a==2){
  25. perfecto(num);
  26. }
  27. a=0;
  28. }
  29. }
  30.  
  31. void perfecto(int num){
  32. int auxUno=0, auxDos=0;
  33. char perfecto[100];
  34. auxUno = pow(2,num-1);
  35. auxDos = pow(2,num)-1;
  36. sprintf(perfecto,"%d", auxUno * auxDos);
  37.  
  38. printf("\n %s ", perfecto);
  39. }

      (http://i61.tinypic.com/121cs3r.jpg)

Lo que me traen son 2 consultas:
La primera es, porque el error del quinto número perfecto, según estas 2 páginas el quinto  debería ser 33 550 336 y a mí me sale en el sexto lugar.- 
http://es.wikipedia.org/wiki/N%C3%BAmero_perfecto
http://curiotecnology.blogspot.com.ar/2012/05/los-5-numeros-perfectos-java.html
La segunda, ¿se puede poner los dos resultado (auxUno y auxDos) en un arreglo de char y multiplicarlos para alojarlo en la variable perfecto?, esto me surge porque el séptimo número perfecto no cabe en una variable del tipo int.-
Espero haberme explicado lo suficiente.-

Saludos.
Daniel   


Título: Re: Números perfectos (lenguaje C)
Publicado por: engel lex en 27 Septiembre 2014, 19:49 pm
el quito numero es algo que no había leido, la forma da los perfectos cuando n es primo... y diferente de 11, aparentemente 11 es el unico primo no perfecto... disculpas por lo haber visto eso D:

este es mi código usando desplazamiento de bits solo por muestra como sería según yo  ;)

comentado y usando iostream porque me da pereza el printf  ;D

no uso el metodo 2 pero funciona

Código
  1. #include <stdio.h>
  2.  
  3. long unsigned int numero_perfecto_metodo1(int primo);
  4. long unsigned int numero_perfecto_metodo2(int primo);
  5. bool es_primo(int numero);
  6.  
  7. int main(void){
  8. unsigned long int perfecto;//para 64 bits completos de precision
  9. int actual;
  10. for(actual = 2; actual <=31; actual++){ //recorre primos del 2 al 27
  11. if(actual==11)actual = 13; //descarto el error del 11
  12. if(es_primo(actual)){ //si el numero actual es primo
  13. perfecto = numero_perfecto_metodo1(actual); //evaluo
  14. printf("%d = resultado:\t %lu \n",actual,perfecto);
  15. }
  16. }
  17. return 0;
  18. }
  19. long unsigned int numero_perfecto_metodo1(int primo){
  20. unsigned long int resultado;
  21. resultado = 1<<(primo-1);
  22. resultado *= (1<<primo)-1;//a*=b es lo mismo que a= a*b
  23. return resultado;
  24. }
  25. long unsigned int numero_perfecto_metodo2(int primo){
  26. unsigned long int resultado;
  27. resultado = (unsigned long int)((1<<primo)-1)<<(primo-1);//necesita casting (?)
  28. return resultado;
  29. }
  30. bool es_primo(int numero){
  31. if(numero == 2) return true; //2 es primo
  32. if(numero % 2 == 0) return false; //ningun multiplo de 2 es primo
  33. int prueba;
  34. for(prueba = 3;prueba*prueba < numero; prueba+=2){ //solo hasta la raiz
  35. if(numero%prueba==0) return false; //si tiene multiplo no es primo
  36. }
  37. return true; //entonces si es primo
  38. }

ese metodo de primos está bien documentado aquí en el foro, un numero para saber primo solo hay que investigar hasta su raiz, más allá todo se repite, al excluir los 2 al final el tiempo de calculo se baja desde "n" ciclos hasta "raiz(n) /2" ciclos ej, el 1.000.001 baja de ser 1.000.001 ciclos hasta 500...

para ser sincero se que el metodo 2 necesita casting de tipo, pero no estoy seguro por que...


Título: Re: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 27 Septiembre 2014, 20:17 pm
Hola.
Con el siguiente programita queda demostrado que el 11 primo no es un número perfecto.-

Código
  1. #include <stdio.h>
  2.  
  3. int main(void){
  4. int a = 33550336, i, res=0;
  5. printf("\n\n");
  6. for(i=1; i<100000000; i++){
  7. if(a%i == 0){
  8. res += i;
  9. if(a == res){
  10. printf("%10d \n ========== \n%10d", i, res);
  11. break;
  12. }
  13. else{
  14. printf("%10d\n", i);
  15. }
  16. }
  17. }
  18.  
  19. printf("\n\n");
  20. return 0;
  21. }

En el caso del programa tuyo lamentablemente no lo voy a poder correr porque desconozco totalmente C++, me gustaría saber cuál es el perfecto más grande que logras, pero bueno…

Saludos.
Daniel   


Título: Re: Números perfectos (lenguaje C)
Publicado por: engel lex en 27 Septiembre 2014, 20:33 pm
ya, puedes copiar de mi ultimo post, modificadas 3 lineas del codigo para hacerlo 100% c  ;D

en
Código
  1. printf("%d = resultado:\t %lu \n",actual,perfecto);

\t es una tabulacion para un espaciador "justificado"
%lu es para imprimir un long unsigned int (%u es unsigned int, %l es long int y se mezclan en uno)


Título: Re: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 27 Septiembre 2014, 21:18 pm
Hola.
Por suerte no puedo ver el movimiento de tus manos ni el gesto de tú cara al leerme nuevamente, tenele un poco de paciencia al “abuelo” Daniel.- ;D ;D ;D
Me podría decir como corregir los siguiente errores, según tengo leído true y false no existen en c.-

(http://i62.tinypic.com/28vab8p.png)

Saludos.
Daniel   


Título: Re: Números perfectos (lenguaje C)
Publicado por: engel lex en 27 Septiembre 2014, 21:48 pm
oh... sorry! :P ya voy a arreglarlo, casi no trabajo en c y olvido que no tiene booleanos  :-X

Código
  1. #include <stdio.h>
  2. #define true 1
  3. #define false 0
  4. long unsigned int numero_perfecto_metodo1(int primo);
  5. long unsigned int numero_perfecto_metodo2(int primo);
  6. int es_primo(int numero);
  7.  
  8. int main(void){
  9. unsigned long int perfecto;//para 64 bits completos de precision
  10. int actual;
  11. for(actual = 2; actual <=31; actual++){ //recorre primos del 2 al 27
  12. if(actual==11)actual = 13; //descarto el error del 11
  13. if(es_primo(actual)){ //si el numero actual es primo
  14. perfecto = numero_perfecto_metodo1(actual); //evaluo
  15. printf("%d = resultado:\t %lu \n",actual,perfecto);
  16. }
  17. }
  18. return 0;
  19. }
  20. long unsigned int numero_perfecto_metodo1(int primo){
  21. unsigned long int resultado;
  22. resultado = 1<<(primo-1);
  23. resultado *= (1<<primo)-1;//a*=b es lo mismo que a= a*b
  24. return resultado;
  25. }
  26. long unsigned int numero_perfecto_metodo2(int primo){
  27. unsigned long int resultado;
  28. resultado = (unsigned long int)((1<<primo)-1)<<(primo-1);//necesita casting (?)
  29. return resultado;
  30. }
  31. int es_primo(int numero){
  32. if(numero == 2) return true; //2 es primo
  33. if(numero % 2 == 0) return false; //ningun multiplo de 2 es primo
  34. int prueba;
  35. for(prueba = 3;prueba*prueba < numero; prueba+=2){ //solo hasta la raiz
  36. if(numero%prueba==0) return false; //si tiene multiplo no es primo
  37. }
  38. return true; //entonces si es primo
  39. }

cambié bool por int y definí true y false


Título: Re: Números perfectos (lenguaje C)
Publicado por: Blaster en 27 Septiembre 2014, 22:17 pm
Para generar los cinco números perfectos conocidos (6, 28, 496, 8128, 33550336) con la formula de  Euclides es necesario trabajar con los primos de mersenne (2, 3, 5, 7, 13)  aquí un ejemplo :

Código
  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <limits.h>
  4.  
  5. typedef enum { FALSE = 0, TRUE = 1 } BOOL;
  6.  
  7. BOOL is_prime( int p )
  8. {
  9.    if( p == 2 ) return TRUE;
  10.    else if( p <= 1 || p % 2 == 0 ) return FALSE;
  11.    else
  12.    {
  13.        BOOL prime = TRUE;
  14.        const int to = sqrt(p);
  15.        int i;
  16.        for(i = 3; i <= to; i+=2)
  17.            if (!(prime = p % i))break;
  18.        return prime;
  19.    }
  20. }
  21.  
  22. BOOL is_mersenne_prime( int p )
  23. {
  24.    if( p == 2 )
  25.        return TRUE;
  26.    else
  27.    {
  28.        unsigned m_p = ( 1U << p ) - 1;
  29.        unsigned s = 4;
  30.        int i;
  31.        for (i = 3; i <= p; i++)
  32.            s = (s * s - 2) % m_p;
  33.        return s == 0;
  34.    }
  35. }
  36.  
  37. int main(void)
  38. {
  39.    int p;
  40.  
  41.    for( p = 2; p <= 13; p += 1 )
  42.        if( is_prime(p) && is_mersenne_prime(p) )
  43.           numero_perfecto(p);
  44.           /*printf("%d ", p);*/
  45.    printf("\n");
  46.  
  47.    return 0;
  48. }
  49.  

Un Saludo


Título: Re: Números perfectos (lenguaje C)
Publicado por: engel lex en 27 Septiembre 2014, 22:28 pm
Blaster seguro que solo con los primos de mersenne?

es decir...son los numeros tal que

(http://upload.wikimedia.org/math/d/e/9/de90513728abb241a608aaa1ac5c457f.png)
Citar
where p is assumed prime.

entonces la secuencia da
Citar
22-1 = 3
23-1 = 7
25-1 = 31

no están el 2, 5, 13, 17,23... sin embargo son tomados en la secuencia de los perfectos... así que creo que la teoría es incorrecta


Título: Re: Números perfectos (lenguaje C)
Publicado por: Blaster en 27 Septiembre 2014, 23:52 pm
Blaster seguro que solo con los primos de mersenne?

entonces la secuencia da
no están el 2, 5, 13, 17,23... sin embargo son tomados en la secuencia de los perfectos... así que creo que la teoría es incorrecta

Con el algoritmo que propuse por supuesto se obtienen esa secuencia de primos menos el 23 el cual no forma parte de la secuencia de números perfectos en ves debes incluir el tres. Estoy utilizando la prueba de Lucas-Lehmer :

http://es.wikipedia.org/wiki/Test_de_Lucas-Lehmer (http://es.wikipedia.org/wiki/Test_de_Lucas-Lehmer)

Para descartar todos los primos no valido, por otra parte en la función es_primo en tu código tienes un pequeño error la condición del for debe quedar así

Código
  1. prueba*prueba <= numero

Debido a esto validaba el nueve como un primo




Título: Re: Números perfectos (lenguaje C)
Publicado por: NOB2014 en 28 Septiembre 2014, 00:58 am
Hola.
Estoy de acuerdo y con esa modificación los primos están correctos pero los perfectos me parece que no.-
 
(http://i62.tinypic.com/2s9spic.png)

Saludos.
Daniel   


Título: Re:
Publicado por: ivancea96 en 28 Septiembre 2014, 01:12 am
Usa unsigned long long, para números más grandes.


Título: Re: Números perfectos (lenguaje C)
Publicado por: Blaster en 28 Septiembre 2014, 04:48 am
Estoy de acuerdo y con esa modificación los primos están correctos pero los perfectos me parece que no.-

El problema con el código del compañero es que de igual manera procesa los primos no validos (23, 29) y también mencionar el desbordamiento de enteros producido, he aquí un ejemplo que calcula los ocho números perfectos :

Código
  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <limits.h>
  4.  
  5. typedef enum { FALSE = 0, TRUE = 1 } BOOL;
  6.  
  7. BOOL is_prime( int p )
  8. {
  9.    if( p == 2 ) return TRUE;
  10.    else if( p <= 1 || p % 2 == 0 ) return FALSE;
  11.    else
  12.    {
  13.        BOOL prime = TRUE;
  14.        const int to = sqrt(p);
  15.        int i;
  16.        for(i = 3; i <= to; i+=2)
  17.            if (!(prime = p % i))
  18.                break;
  19.        return prime;
  20.    }
  21. }
  22.  
  23. BOOL is_mersenne_prime( int p )
  24. {
  25.    if( p == 2 )
  26.        return TRUE;
  27.    else
  28.    {
  29.        long long unsigned m_p = ( 1U << p ) - 1;
  30.        long long unsigned s = 4;
  31.        int i;
  32.        for (i = 3; i <= p; i++)
  33.        {
  34.            s = (s * s - 2) % m_p;
  35.        }
  36.        return s == 0;
  37.    }
  38. }
  39.  
  40. int main(int argc, char **argv)
  41. {
  42.    const int upb = log2l(ULLONG_MAX)/2;
  43.    int p;
  44.  
  45.    for( p = 2; p <= upb; p++ )
  46.    {
  47.        if( is_prime(p) && is_mersenne_prime(p) )
  48.            printf(" %llu\n", (long long unsigned)(1U << (p - 1)) * ((1U << p) - 1));
  49.    }
  50.    printf("\n");
  51.  
  52.    return 0;
  53. }
  54.  

Puedes comprobarlo aquí :

http://www.vaxasoftware.com/doc_edu/mat/numperfe_esp.pdf

Un saludo


Título: Re: Números perfectos (lenguaje C)
Publicado por: rir3760 en 30 Septiembre 2014, 04:34 am
me diste algo que investigar, estuve viendo la progesion completa (sin importar si eran primos o no) en binario y son muy simple en ese aspecto... pero me da un error que no descubro la razón
El problema es que solo presentas la salida del programa, sin el código fuente no es posible conocer la causa del error (imagino tiene que ver con tu otra duda).

para ser sincero se que el metodo 2 necesita casting de tipo, pero no estoy seguro por que
El segundo metodo es:
Código
  1. long unsigned int numero_perfecto_metodo2(int primo)
  2. {
  3.   unsigned long int resultado;
  4.   resultado = (unsigned long int) ((1 << primo) - 1) << (primo - 1);
  5.   return resultado;
  6. }
El cual se puede abreviar a:
Código
  1. long unsigned int numero_perfecto_metodo2(int primo)
  2. {
  3.   return ((1 << primo) - 1) << (primo - 1);
  4. }
El problema ahí es la primera literal 1, esta es de tipo signed int y puede, dependiendo del desplazamiento, generar un numero negativo. Para solucionarlo lo mas fácil es indicar que el tipo de ella es unsigned long mediante sufijos: 1UL.

Un saludo