Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: minari02 en 24 Diciembre 2013, 01:00 am



Título: codigo para calcular los numeros primos
Publicado por: minari02 en 24 Diciembre 2013, 01:00 am
Hola que tal, he empezado con C++ hace poco, hay un ejercicio bastante concurrido cuando se esta estudiando programación y es de imprimir en pantalla números con ciertos rangos, uno de ellos es el de los números primos, creo que un no soy capaz por decirlo asi de poder programar dicho codigo, buscando, me he encontrado este código
Código:

#define LIMITE 35000
int main ()
{
   int i, j, primo, num;
   printf ("Introduzca numero: ");
   scanf ("%d", &num);
   i = num + 1;
   do
   {
      primo = 1;
      for (j = 2; j <= i/2 && primo; j++)
         if((i%j) == 0)
            primo = 0; 
      if (primo)
         printf("%d\n", i);   
      i++;   
   }while ( i < LIMITE && !primo);
   system("pause");
   return 0;
}
 

he intentado entenderlo pero hay algunas cosas que aun no comprendo, son pequeñas cosas, asi que desearía saber si por favor me ayudarían a comprenderlo, poniendo como comentario como funciona cada linea, bueno los temas que he visto son: funciones de entrada(con libreria stdio y iostream),tipos de datos,if y else,operadores logicos, ciclo while, ciclo for(hoy) todo de una manera superficial, que opinan ya deberia saber hacerlo?

Gracias.

pd: he visto que algunos se molestan con algunas preguntas algo asi... por que son preguntas talvez de tareas o similares, sin embargo... estén sin cuidado, yo ya he terminado el colegio y pues.. esto es solo algo que me apasiona y ps deseo aprenderlo aun por mi propia cuenta.jaja

Saludos. Feliz Navidad jeje...  ;-)  :laugh:  :xD  :rolleyes:


Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 24 Diciembre 2013, 01:08 am
Código
  1. #define LIMITE 35000
  2. int main ()
  3. {
  4.   int i, j, primo, num;
  5.   printf ("Introduzca numero: ");
  6.   scanf ("%d", &num);
  7.   i = num + 1;
  8.   do
  9.   {
  10.      primo = 1;
  11.      for (j = 2; j <= i/2 && primo; j++) //Pasamos por todos los números hasta i/2
  12.         if((i%j) == 0) //Si se encuentra un divisor (i/j -> resto==0) se pone que primo es = a 0
  13.            primo = 0;
  14.      if (primo) //Si es primo, lo escribe
  15.         printf("%d\n", i);    
  16.      i++;    //Aumenta 'i', para ir al siguiente número
  17.   }while ( i < LIMITE && !primo);
  18.   system("pause");
  19.   return 0;
  20. }
  21.  

Sencillamente, mira todos los números, desde 2 hasta la mitad del número, para ver si alguno es divisor. Si alguno lo es, resulta que no es primo, y primo = 0.

El programa mira el primer número superior al número que tú le introduces.

Acerca de lo de i/2, es porque, si no es divisible por 2, tampoco es divisible por su mitad. Así se ahorra mucho tiempo en números grandes.


Título: Re: codigo para calcular los numeros primos
Publicado por: minari02 en 24 Diciembre 2013, 01:19 am
Hola amigo, gracias por tu respuesta  ;-), me podrias expricar para que sirve el %? no lo habia visto asi, solo %d, %c, f%


Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 24 Diciembre 2013, 01:52 am
5/2, en números enteros, da de resultado 2.
5%2, en números enteros, da de resultado 1.

% da el resto de una operación.


Título: Re: codigo para calcular los numeros primos
Publicado por: minari02 en 24 Diciembre 2013, 03:23 am
mm.. amigo me podria decir que significa esta linea
Código:
printf("%4d",1);
creo que es muy importante, trate de cambiarla para entender mejor como funciona cada parte del programa y pues... simplemente sale un error es asi :
Código:
floating point exception (core dumped)
y pues... estuve buscando pero no se como se llama y no pude encontrar info sobre ello.

Gracias.


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 24 Diciembre 2013, 04:26 am

Respuesta en que_significa_y_como_se_llama_printf4d1_en_c (http://foro.elhacker.net/programacion_cc/que_significa_y_como_se_llama_printf4d1_en_c-t405457.0.html)

No dupliques los temas, ya lo habías preguntado aquí. Espera que te contesten en lugar de abrir un nuevo tema con la misma pregunta que en este  tema.
:rolleyes:

Felices Navidades y Próspero Año Nuevo.

Saluditos! ..... !!!!

(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)




Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 24 Diciembre 2013, 10:29 am
Sencillamente, mira todos los números, desde 2 hasta la mitad del número
En realidad sería hasta la raiz del número.

Ponte el caso con 36, el máximo divisor aquí es 6 (lo que viene a ser 6x6). Cualquier número que encuentres superior a eso 12 (12x3) no será nada más que el inverso de uno anterior (3x12).

También podríamos generarnos una tabla booleana diciendo cual es primo y cual no. Usando la criba de eratostenes (mira el gif):
http://es.wikipedia.org/wiki/Criba_de_Erat%C3%B3stenes


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 24 Diciembre 2013, 15:03 pm
En realidad sería hasta la raiz del número.

El caso es si sabe donde se pone la raíz cuadrada. Y no olvidarse de incluir la librería math.h.


También podríamos generarnos una tabla booleana diciendo cual es primo y cual no. Usando la criba de eratostenes (mira el gif):
http://es.wikipedia.org/wiki/Criba_de_Erat%C3%B3stenes


A mi modesto entender, ello implica calcular y guardar en arrays los sucesivos múltiplos de 2,3,5, etc para posteriormente por comparación comprobar que no está en ellos. A mí por lo menos me ha dado una pobre eficiencia, supongo que debido al cambio de calcular si un módulo es cero por el tener que rellenar arrays y posteriormente comparar. Igual tu lo tienes más optimizado.

Una pequeña mejora, además de lo de la raíz, es ir comprobando sólo los impares, ya que sabemos que los pares, excepto el 2, no son primos:


Código
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. int main()
  5. {
  6.    int n,i,j,rq;
  7.    printf("Introduce el numero por favor: ");
  8.    fflush (stdout);
  9.    scanf("%d",&n);
  10.    if (n==1){
  11.        printf("2");
  12.        return 1;
  13.    }
  14.    printf("2");
  15.    fflush (stdout);
  16.    for (i = 3;i <= n;i+=2){
  17.  
  18.        j = 3;
  19.        while (j <= rq && i % j != 0)
  20.            j++;
  21.        if (i == j){
  22.            printf("%4d",j);
  23.            fflush (stdout);
  24.        }
  25.    }
  26.    return 0;
  27. }
  28.  

No es el más efiiciente pero no quería cambiarle sustancialmente su código. :rolleyes: :rolleyes: :rolleyes:

Felices Navidades y Próspero Año Nuevo.

Saluditos! ..... !!!!

(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 24 Diciembre 2013, 15:16 pm
Leosansan, no estableces en ningún momento el valor de la variable "rq".

Código
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. int main()
  5. {
  6.    int n,i,j,rq;
  7.    printf("Introduce el numero por favor: ");
  8.    fflush (stdout);
  9.    scanf("%d",&n);
  10.    if (n==1){
  11.        printf("2");
  12.        return 1;
  13.    }
  14.    printf("2");
  15.    fflush (stdout);
  16.    for (i = 3;i <= n;i+=2){
  17.        rq = sqrt(i);
  18.        j = 3;
  19.        while (j <= rq && i % j != 0)
  20.            j++;
  21.        if (i == j){
  22.            printf("%4d",j);
  23.            fflush (stdout);
  24.        }
  25.    }
  26.    return 0;
  27. }


Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 24 Diciembre 2013, 15:48 pm
El caso es si sabe donde se pone la raíz cuadrada. Y no olvidarse de incluir la librería math.h.
No hace falta usar la librería math.h, estamos hablando de la raiz entera:

Código
  1. for (i = 2; (i*i) <= n;i++)

A mi modesto entender, ello implica calcular y guardar en arrays los sucesivos múltiplos de 2,3,5, etc para posteriormente por comparación comprobar que no está en ellos. A mí por lo menos me ha dado una pobre eficiencia, supongo que debido al cambio de calcular si un módulo es cero por el tener que rellenar arrays y posteriormente comparar. Igual tu lo tienes más optimizado.
No guardo los primos, sino todos los numeros naturales hasta N. Te dejo aquí el código:

Código
  1. #include <stdio.h>
  2. #define PRIMO 1
  3. #define COMPUESTO 0
  4. #define NO_DEFINIDO -1
  5.  
  6. const int MAX = 120;
  7.  
  8. void tacharMultiplos(char Tabla[],int N)
  9. {
  10.    int i;
  11.    for (i = 2;(N*i) <= MAX;i++)
  12.    {
  13.        Tabla[N*i] = COMPUESTO;
  14.    }
  15. }
  16.  
  17. void mostrarTabla(char Tabla[])
  18. {
  19.    int i = 2;
  20.    for (; i <= MAX;i++)
  21.        if (Tabla[i] == PRIMO) printf("%d\n",i);
  22. }
  23.  
  24. int main()
  25. {
  26.    // Generar Criba de erastotenes
  27.  
  28.    char Tabla[MAX+1]; // tabla booleana
  29.    int i = 0;
  30.  
  31.    // valor inicial
  32.  
  33.    for (; i<= MAX;i++) Tabla[i] = NO_DEFINIDO;
  34.  
  35.    for (i = 2;i<=MAX;i++)
  36.    {
  37.        if (Tabla[i] == NO_DEFINIDO) // si no esta inicializada...
  38.        {
  39.            Tabla[i] = PRIMO;
  40.            tacharMultiplos(Tabla,i);
  41.        }
  42.    }
  43.  
  44.    mostrarTabla(Tabla);
  45.    return 0;
  46. }

Si haces una solo comprobación no te sale rentable, pero si vas a hacer muchas comprobaciones te puede venir bien generarte esa tabla. De esa forma, cualquier comprobación que necesites hacer la puedes sacar instantaneamente para cualquier número <= MAX:

Código
  1. scanf("%d",&numero);
  2. if (numero < max)
  3. {
  4.  if (Tabla[numero]) puts("Es primo");
  5.  else puts("Es compuesto");
  6. }
  7. else
  8. {
  9.  if (esPrimo(numero)) puts("Es primo");
  10.  else puts("Es compuesto");
  11. }


Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 24 Diciembre 2013, 16:19 pm
El problema de eso, yo se lo veo cuando tratámos números grandes. Véase 10^9.


Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 24 Diciembre 2013, 16:33 pm
El problema de eso, yo se lo veo cuando tratámos números grandes. Véase 10^9.
¿Que problema hay con eso? El bucle hace raiz(n) iteraciones (es decir, es muy eficiente). En el caso que tu propones haría 10^3 iteraciones.

Cualquier cpu puede hacer 1000 iteraciones de un bucle en una soplada:
http://imageshack.us/a/img542/3319/0133.png

Si te refieres a generar la tabla completa (y no al calculo directo). Su complejidad es n*log n (más lento, pero también es eficiente). A mi me tarda poco (tardo unos 2 segundos en generar la tabla con todos los primos a 10 ^ 9).


Título: Re: codigo para calcular los numeros primos
Publicado por: minari02 en 24 Diciembre 2013, 23:47 pm
Hola, que tal?

Muchas gracias por sus respuestas y creo que el mas simplificado es de amchacon he puesto su codigo y funciona perfecto aunque lo que no entiendo es como rayos funciono sin incluir la libreria y sin poner el
Código:
int main
bien ya antes habia encontrado un codigo funcional, el cual ya he mostrado a leosansan y me ha hecho las correciones necesarias y pues aqui lo posteo:

Código
  1.    #include <stdio.h>
  2.  
  3.    int main()
  4.    {
  5.       int n,i,j;
  6.       printf("Introduce el numero por favor: ");
  7.       fflush (stdout);
  8.       scanf("%d",&n);
  9.       printf("%4d",1);//dejar una memoria reservada para introducir un numero de cuatro digitos y empezar a contar de 1//
  10.       for (i = 2;i <= n;i++){//empezar desde 2 hasta que i sea menor o igual que "n" (numero introducido) incrementar 1//
  11.           j = 2;
  12.           while (j <= i && i % j != 0)//mientras j sea 2 y sea menor que o igual a i que t no sera 2 por
  13.                                      //el incremento y que el resto de la divicion de entre "i" y "j" sea diferente a 0//
  14.               j++; //hacer incremento en j;
  15.           if (i == j){//si "i" es igual a "j" imprimir j
  16.               printf("%4d",j);
  17.               fflush (stdout);
  18.           }
  19.       }
  20.       return 0;
  21.    }
  22.  

Ok.. los comentarios los he puesto yo, si hay error avísenme, por cierto que aqui se usa claramente el algoritmo La criba de Eratóstenes.

no digo que sea mejor, si no que la forma mas basica y entendible. supongo que la mejor seria la de  amchacon  que piensan?

saludos  :P


Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 25 Diciembre 2013, 12:27 pm
Hola, que tal?

Muchas gracias por sus respuestas y creo que el mas simplificado es de amchacon he puesto su codigo y funciona perfecto aunque lo que no entiendo es como rayos funciono sin incluir la libreria y sin poner el
Código:
int main
¿Ein?

Está el int main y el #include <stdio.h>. Vuelvetelo a mirar que además lo tuve que editar para mejorar su eficiencia.
Ok.. los comentarios los he puesto yo, si hay error avísenme, por cierto que aqui se usa claramente el algoritmo La criba de Eratóstenes.

no digo que sea mejor, si no que la forma mas basica y entendible. supongo que la mejor seria la de  amchacon  que piensan?

saludos  :P
Ese código no es la criba de erástotenes  :silbar:


Título: Re: codigo para calcular los numeros primos
Publicado por: minari02 en 25 Diciembre 2013, 20:35 pm
jeje... si ya me he dado cuenta  :xD  :rolleyes:  ;D  :silbar:


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 27 Diciembre 2013, 21:25 pm
jeje... si ya me he dado cuenta  :xD  :rolleyes:  ;D  :silbar:

Perdona que había quedado en contestar, pero esto de las Fiestas me ocupan familiarmente demasiado.

No quería dejar pasar mi versión de la criba de Eratóstenes, para que no se diga que no ayudamos:


Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main ()
  5. {
  6.    int i, j, cont=1, n;
  7.    //printf ("Introduzca numero: ");
  8.    //scanf ("%d", &n);
  9.    n=1000000;
  10.    int *a;
  11.    a =  malloc (sizeof(int)*n);
  12.    for (i=3;i<=n;i+=2)
  13.        a[i]=i;
  14.    /*printf ("2  ");*/
  15.    for (i=3; i*i<=n;i+=2)
  16.        for (j=i;i*j<=n;j+=2)
  17.            a[i*j]=0;
  18.    for (i=3;i<n;i+=2)
  19.        if (a[i]!=0){
  20.            //printf ("%d  ",a[i]);
  21.            cont++;/**/
  22.        }
  23.    printf("\n total = %d",cont);
  24.    free (a);
  25.    return 0;
  26. }
  27.  

Sí. ya sé que están desactivados el scanf y el printf, pero quería compararlo con el de amchacon  :laugh: :laugh: Y esto son los resultados, desactivando también los printf en el de amchacon y dejando en ambos casos activo solamente el contador final de primos resultantes:

(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/cribaleon_zps5d4bb05a.jpg)

(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/cribaamchacon_zpsa48b33dd.jpg)

No es por nada  :laugh: :laugh: pero parece que el mío va de un 25 a un 33 por ciento más rápido, y eso que solamente he podido usar 10^6, cuando en realidad quería meterle más caña, pero ...... en el mío no tengo problema en tomar 10^8, pero el de amchacon se cuelga en mi ordenador desde 10^7. Supongo que es problema mío, y de tener declarada la matriz en el caso de amchacon como int[]. Es un fastidio porque, como ejemplo, no puedo usar en mi ordenata matrices de 1000x1000. ¡SNIFFF!. ¿Os pasa algo parecido a vosotros o podéis manejar rangos superiores a 10^8 o matrices de orden superior a 1000?.

¡OJO!, que los comentarios son en tono jocoso y festivos, que es lo que se lleva por estas fechas.  ;) ;) Nada de piques, ¿vale?.
EN realidad amigo amchacon, tu código me parece una virguería, demuestras unos amplios conocimientos incluso en algo tan simple como el ejemplo que nos ocupa. Espero por lo menos llegar a aproximarme con el tiempo .... y una caña para que sea más llevadero. :laugh: :laugh:


;-)  ;-) Felices Navidades y Próspero Año Nuevo.  ;-)  ;-)


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 27 Diciembre 2013, 21:47 pm
Man prueba con 10^12 :O


Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 27 Diciembre 2013, 22:43 pm
Perdona que había quedado en contestar, pero esto de las Fiestas me ocupan familiarmente demasiado.

No quería dejar pasar mi versión de la criba de Eratóstenes, para que no se diga que no ayudamos:


Código
  1. #include <stdio.h>
  2.  
  3. int main ()
  4. {
  5.    int i, j, cont=1, n;
  6.    //printf ("Introduzca numero: ");
  7.    //scanf ("%d", &n);
  8.    n=1000000;
  9.    int *a;
  10.    a =  malloc (sizeof(int)*n);
  11.    for (i=3;i<=n;i+=2)
  12.        a[i]=i;
  13.    /*printf ("2  ");*/
  14.    for (i=3; i*i<=n;i+=2)
  15.        for (j=i;i*j<=n;j+=2)
  16.            a[i*j]=0;
  17.    for (i=3;i<n;i+=2)
  18.        if (a[i]!=0){
  19.            //printf ("%d  ",a[i]);
  20.            cont++;/**/
  21.        }
  22.    printf("\n total = %d",cont);
  23.    return 0;
  24. }
  25.  

Sí. ya sé que están desactivados el scanf y el printf, pero quería compararlo con el de amchacon  :laugh: :laugh: Y esto son los resultados, desactivando también los printf en el de amchacon y dejando en ambos casos activo solamente el contador final de primos resultantes:

(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/cribaleon_zps5d4bb05a.jpg)

(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/cribaamchacon_zpsa48b33dd.jpg)

No es por nada  :laugh: :laugh: pero parece que el mío va de un 25 a un 33 por ciento más rápido, y eso que solamente he podido usar 10^6, cuando en realidad quería meterle más caña,
Los tiempos son muy cortos para suponer eso, ahí puede influir muchos factores externos.

Pero aún así es más eficiente, entre otras cosas porque no tienes llamadas a función y esas cosas. El algoritmo es el mismo básicamente.

pero ...... en el mío no tengo problema en tomar 10^8, pero el de amchacon se cuelga en mi ordenador desde 10^7. Supongo que es problema mío, y de tener declarada la matriz en el caso de amchacon como int[]. Es un fastidio porque, como ejemplo, no puedo usar en mi ordenata matrices de 1000x1000. ¡SNIFFF!. ¿Os pasa algo parecido a vosotros o podéis manejar rangos superiores a 10^8 o matrices de orden superior a 1000?.
El problema esque yo meto los datos en la pila y tú usas memoria dinámica (malloc).

Tienes la explicación detallada aquí (segundo mensaje):
http://foro.elhacker.net/programacion_cc/duda_memoria_dinamica_en_c-t391783.0.html

Man prueba con 10^12 :O
Te sales del rango de los enteros  :silbar:


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 27 Diciembre 2013, 22:59 pm
.......................................................................................

Pero aún así es más eficiente, entre otras cosas porque no tienes llamadas a función y esas cosas. El algoritmo es el mismo básicamente.
.......................................

Supongo que también influye el hecho de que yo empiezo en 3 y voy de dos en dos, obviando de esa forma las operaciones con los pares, que no son primos ni son pocos. Lo que más me ha gustado es la concisión en el código ;)

¡¡¡¡ Saluditos! ..... !!!!


Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 27 Diciembre 2013, 23:15 pm
Supongo que también influye el hecho de que yo empiezo en 3 y voy de dos en dos, obviando de esa forma las operaciones con los pares, que no son primos ni son pocos. Lo que más me ha gustado es la concisión en el código ;)

¡¡¡¡ Saluditos! ..... !!!!

Ah pues no había pensado en eso. Quizás eso haya sido lo más decisivo xD


Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 27 Diciembre 2013, 23:21 pm
Ei, no me ignoreis! Quiero ver como os revienta la RAM usando eso para 10^12 xD


Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 27 Diciembre 2013, 23:26 pm
Ei, no me ignoreis! Quiero ver como os revienta la RAM usando eso para 10^12 xD
Te he contestado, 10^12 se sale del rango de una variable int xD.

Y sería una tabla de 900 mb, yo desde luego ahí dejaría de crearme la tabla de erastotenes y haría la función esPrimo().


Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 27 Diciembre 2013, 23:27 pm
Long long :D

Y, si mis calculos no son erróneos:

Citar
8  * 10^12 bytes
8*10^9 kilobytes
8*10^6 megabytes
8*10^3 Gigabytes
8*10 terabytes

:O


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 27 Diciembre 2013, 23:55 pm
Long long :D

Y, si mis calculos no son erróneos:


10^12 supera las cifras del long long int.

¡¡¡¡ Saluditos! ..... !!!!



Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 28 Diciembre 2013, 00:37 am
las cifras de long long int, al menos en mi pc, son de 10^18 x)


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 28 Diciembre 2013, 01:04 am
las cifras de long long int, al menos en mi pc, son de 10^18 x)

Hablo de cifras como entero, que es lo que procede en los primos. ¿Qué maquinón estas usando y qué compilador?. El mío es de 64 bits y Core I7 con 8 Gb de memoria y un tera de disco duro. Tiene tres añitos pero creo que aún no está obsoleto.

Mis limites para un int son:


(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/limitesleon_zpscd460526.jpg)

Sería cuestión de probar con long long int.

P.D:Ya probado, el máximo que admite es 10^8.


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 28 Diciembre 2013, 01:20 am
Como se hace para int, se puede hacer para long long.
long long int -> 8 bytes
8 bytes -> 64 bits
2^64 = 18.446.744.073.709.551.616
18 trillones.


Título: Re: codigo para calcular los numeros primos
Publicado por: minari02 en 28 Diciembre 2013, 01:25 am
oooh...  :o :o :o  ustedes son medio genios no?? jajjaja... esto solo me hace pensar que me hace falta como 2 años para poder alcanzarlos o estar cerca...  :P :P :P


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 28 Diciembre 2013, 10:55 am
Como se hace para int, se puede hacer para long long.
long long int -> 8 bytes
8 bytes -> 64 bits
2^64 = 18.446.744.073.709.551.616
18 trillones.

Aproximadamente la mitad para los positivos y la otra mitad para los negativos.

El problema no es imprimir 10^18, que si lo acepta, sino que a partir de 10^9 malloc no lo acepta, lo que impone esa limitación en el consiguiente cálculo de los primos. Presupongo que ello se debe al uso de la memoria y en 10^9 ya estaríamos hablando de Gigabyte, si no me salen mal las cuentas con la limitación correspondiente de la memoria en uso por el ordenador.

¡¡¡¡ Saluditos! ..... !!!!

:rolleyes: ;) ;) ;) :rolleyes:



Título: Re: codigo para calcular los numeros primos
Publicado por: ivancea96 en 28 Diciembre 2013, 14:01 pm
oooh...  :o :o :o  ustedes son medio genios no?? jajjaja... esto solo me hace pensar que me hace falta como 2 años para poder alcanzarlos o estar cerca...  :P :P :P

Nah, son cosas q se van aprendiendo con el tiempo. Más básicas de lo que crees jaja


PD: Leosansan, me apasiona tu "firma" :D

(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 28 Diciembre 2013, 14:55 pm
.........................................................
Pero aún así es más eficiente, entre otras cosas porque no tienes llamadas a función y esas cosas. El algoritmo es el mismo básicamente.
El problema esque yo meto los datos en la pila y tú usas memoria dinámica (malloc).
.............................................................

El mismo código tuyo, con mis modificaciones en cuanto a ir de dos en dos, y manteniendo el uso de la pila así como de las funciones es similar al mío:

(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/cribaamchaconleon_zps11f46fd4.jpg)

Código
  1. #include <stdio.h>
  2. #define COMPUESTO 0
  3.  
  4. const int MAX = 1000000;
  5.  
  6. void tacharMultiplos(char Tabla[],int i)
  7. {
  8.    int j;
  9.    for (j = i;(i*j) <= MAX;j+=2)
  10.    {
  11.        Tabla[j*i] = COMPUESTO;
  12.    }
  13. }
  14.  
  15. void mostrarTabla(char Tabla[])
  16. {
  17.    int i = 3,cont=1;
  18.  
  19.    for (i = 3; i <= MAX;i+=2)
  20.    {
  21.        if (Tabla[i] != COMPUESTO)
  22.        {
  23.            /*printf("%d  ",Tabla[i]);*/
  24.            cont++;
  25.        }
  26.  
  27.    }
  28.  
  29.    printf("\ncont= %d\n",cont);
  30. }
  31.  
  32. int main()
  33. {
  34.    // Generar Criba de erastotenes
  35.  
  36.    char Tabla[MAX+1]; // tabla booleana
  37.    int i = 0;
  38.  
  39.    // valor inicial
  40.  
  41.    for (i = 3; i<= MAX;i++)
  42.    {
  43.        Tabla[i] = i;
  44.    }
  45.  
  46.  
  47.    for (i = 3;i*i<=MAX;i+=2)
  48.    {
  49.            tacharMultiplos(Tabla,i);
  50.    }
  51.  
  52.    mostrarTabla(Tabla);
  53.    return 0;
  54. }
  55.  

Eso sí, creo que el uso de la pila penaliza el tamaño del array ya que en mi caso puedo llegar a 10^8 y en el tuyo a 10^6, al menos en mi ordenador.

Y como verás he respetado el uso que haces de las llaves ..... que se me antoja excesivo.  ;) ;) ;)



¡¡¡¡ Saluditos! ..... !!!!

:rolleyes: ;) ;) ;) :rolleyes:


Título: Re: codigo para calcular los numeros primos
Publicado por: amchacon en 28 Diciembre 2013, 16:06 pm
El problema no es imprimir 10^18, que si lo acepta, sino que a partir de 10^9 malloc no lo acepta
Malloc recibe un argumento de tipo size_t, el valor máximo que puede alcanzar está definido con la macro SIZE_MAX (definida en stdint.h). Normalmente suele tener el valor de un unsigned long long (2^64-1).

El problema no está en malloc. El problema son estos dos:

- Estás pidiendo memoria de forma contigua es muy posible que tengas 1 gb libre de memoria ram, el problema esque la memoria libre estará "dispersa". Es muy díficil que te encuentres 1 gb de espacio libre contiguo. Se podría suplir esto usando listas o varios vectores.
- En una aplicación de 32 bits, la máxima memoria permitida es de 2GB (si la compilas en 64 bits llegarías a los 16 tb)

..
Y como verás he respetado el uso que haces de las llaves ..... que se me antoja excesivo.  ;) ;) ;)[/size]
Pues efectivamente, era por saltase iteraciones... Y porque el if que he puesto sobraba  :silbar:

Y no soy tan nazi con las llaves xD. Ahí son pocas sentencias y se ve bastante claro. Yo lo hubiera identado de otra forma:
Código
  1. #include <stdio.h>
  2. #define COMPUESTO 0
  3.  
  4. const int MAX = 1000000;
  5.  
  6. void tacharMultiplos(char Tabla[],int i)
  7. {
  8.    int j;
  9.  
  10.    for (j = i; (i*j) <= MAX; j+=2)
  11.        Tabla[j*i] = COMPUESTO;
  12. }
  13.  
  14. void mostrarTabla(char Tabla[])
  15. {
  16.    int i = 3,cont=1;
  17.  
  18.    for (i = 3; i <= MAX; i+=2)
  19.        if (Tabla[i] != COMPUESTO) cont++;
  20.  
  21.    printf("\ncont= %d\n",cont);
  22. }
  23.  
  24. int main()
  25. {
  26.    // Generar Criba de erastotenes
  27.  
  28.    char Tabla[MAX+1]; // tabla booleana
  29.    int i = 0;
  30.  
  31.    // valor inicial
  32.  
  33.    for (i = 3; i<= MAX; i++)   Tabla[i] = i;
  34.    for (i = 3; i*i<=MAX; i+=2)   tacharMultiplos(Tabla,i);
  35.  
  36.    mostrarTabla(Tabla);
  37.    return 0;
  38. }
  39.  


Título: Re: codigo para calcular los numeros primos
Publicado por: leosansan en 28 Diciembre 2013, 16:35 pm
.....................................................

El problema no está en malloc. El problema son estos dos:

- Estás pidiendo memoria de forma contigua es muy posible que tengas 1 gb libre de memoria ram, el problema es que la memoria libre estará "dispersa". Es muy díficil que te encuentres 1 gb de espacio libre contiguo. Se podría suplir esto usando listas o varios vectores.
- En una aplicación de 32 bits, la máxima memoria permitida es de 2GB (si la compilas en 64 bits llegarías a los 16 tb)
......................................

 ;-) ;-) ;-) Seré pardillo ........ mi memoria es la que si falla.

¡¡¡¡ Saluditos! ..... !!!!

:rolleyes: ;) ;) ;) :rolleyes: