Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: andres_5 en 26 Agosto 2010, 05:10 am



Título: Novato en C...
Publicado por: andres_5 en 26 Agosto 2010, 05:10 am
hola acabo de empezar hoy a programar C, ya que a medida que iba avanzando mis proyectos de electronica me veia limitado al no saber programar C, asique he empezado poco a poco. ahora estoy haciendo un generador y resolvedor de ecuacion de 2º grado...
el codigo es el siguiente (No esta completo pero esta donde me da error.):
Código:
#include <stdio.h>
#include <stdlib.h>
int a, b, c, d, e, f;
int main(int argc, char** argv)
{
a = rand()%9;
b = rand()%21;
c = rand()%21;
d = rand()%21;

printf ("%dx²%dx%d=%d \n", a, b, c, d);
return 0;
}
cuando da el numero al azar solo me da un numero, vamos a ver, me explico, abro la aplicacion y me sale:
1x²4x9=19
y cuando cierro y vuelvo a abrir deberia salir otro numero al azar, no? pues me sale el mismo...

Saludos y estoy programando desde linux y compilando con gcc...


Título: Re: Novato en C...
Publicado por: rob1104 en 26 Agosto 2010, 05:44 am
El problema es que rand() "calcula" los números aleatorios. Parte de un número inicial (llamado semilla), echa unas cuentas y saca un número aleatorio. Para el segundo número, echa unas cuentas con el resultado anterior y saca un segundo número y así sucesivamente.

Si volvemos a ejecutar el programa desde el principio, el número inicial (la semilla) que usa rand() es el mismo, con lo que la secuencia de números aleatorios es la misma, ya que las cuentas son las mismas.

Para evitar este problema tenemos la función srand(), a la que se le pasa de parámetro un número que se utilizará como número inicial para las cuentas. A esta función sólo debemos llamarla una vez en nuestro programa.

¿Qué número le ponemos a este srand()?. No podemos ponerle un número fijo, porque entonces no hemos hecho nada. No podemos ponerle un número obtenido con rand(), porque la primera vez siempre nos dará el mismo y el resultado será igual que si le ponemos un número fijo. Debemos buscar la forma de obtener un número que sea distinto en la ejecución de cada programa.

Hay dos números que se utilizan habitualmente para ello:

1- La fecha/hora del sistema. Este valor cambia si ejecutamos el programa en distinto instante de tiempo. Tendriamos que arrancar el programa dos veces en el mismo segundo para obtener la misma secuencia de números aleatorios. En C de linux esta fecha/hora se obtiene con la función time()

Código:
srand (time(NULL));

2-El número de proceso del programa. El primer programa que se arranca cuando se enciende el ordenador con el sistema operativo linux, tiene el número de proceso 1, el segundo el 2, el tercero el 3 y así sucesivamente. Cuando arrancamos nuestro programa, se le asignará el número que le toque, por ejemplo, el 215. Cuando lo volvamos a arrancar, se le asignará el que le toque (puede ser 216 si no hemos ejecutado nada entre medias o 345, si nos hemos entretenido con otras cosas). Después de ejecutar nuestro programa varios miles de veces, el número de proceso puede que se repita, pero ya no nos acordaremos de la secuencia que se sacó la primera vez. El número de proceso se obtiene con getpid()

Código:
srand (getpid());

Por lo que tu programa quedaria asi:
Código
  1. #include <stdio.h>
  2. #include <time.h>
  3. int a, b, c, d, e, f;
  4. int main(int argc, char** argv)
  5. {
  6.    srand (time(NULL));
  7.    a = rand()%9;
  8.    b = rand()%21;
  9.    c = rand()%21;
  10.    d = rand()%21;
  11.  
  12.    printf ("%dx²%dx%d=%d \n", a, b, c, d);
  13. return 0;
  14. }
  15.  

Saludos


Título: Re: Novato en C...
Publicado por: andres_5 en 26 Agosto 2010, 05:54 am
si me funciona, pero nose si voy a tener problemas en el futuro, ya que tengo pensado hacer un bucle hasta que no salga una solucion entera, he probado tu codigo y funciona, muchas GRACIAS , pero esa es  mi siguiente duda, si este metodo me permitira hacer un bucle y que de una solucion efectiva...
Estoy pensando que esto reelentizara mucho mi aplicacion osea 1 segundo por cada vez que compruebe si la solucion es entera, no? ya que el tiempo cambia cada segundo, no?.
Si hubiese otro metodo mas efectivo aunque sea mas dificil, no me importaria...
aun asi muchas Gracias .saludos
Edito:
Nuevos problemas...
he utilizado la herramienta sqrt para hacer una raiz cuadrada, y ahora me sale este error.
http://i34.tinypic.com/avk11w.png
os pego el codigo aver si veis el error. supongo que sera al manejar los datos.. pero nose, ni tampoco una solucion...

Código:
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int a, b, c, d, e, f;
int a2, b2, c2, d2, e2, f2;
char a1, b1, c1;
int main(int argc, char** argv)
{
srand (time(NULL));
a = rand()%9;
b = rand()%21;
c = rand()%21;
d = rand()%21;
//creamos los numeros negativos
a=a-4;
b=b-10;
c=c-10;
d=d-10;
//Administramos los signo de la ecuacion.
if (a > 0)
{ a1= '+';}
else{a1=' ';}

if (b > 0)
{b1= '+';}
else{b1=' ';}

if (c > 0)
{c1= '+';}
else{c1=' ';}
//Creamos variables secundarias para poder operar comodamente con ellas.
a2 = a;
b2 = b;
c2 = c;
d2 = d;
c2 = c2 + d2;
e2= sqrt((b2*b2)-(4*a2*c2));
e2 = (-(b2)+e2)/(2*a2);
f2 = sqrt((b2*b2)-(4*a2*c2));
f2 = (-(b2)-f2)/(2*a2);

//Presenta la ecuacion con los requisitos aprovados, osea con soluciones reales y enteros.
printf ("%c%dx²%c%dx%c%d=%d \n", a1, a, b1, b, c1, c, d);

return 0;
}


Título: Re: Novato en C...
Publicado por: clodan en 26 Agosto 2010, 15:20 pm
hay un problemita nomas...

en esta parte:

Código
  1. e2= sqrt((b2*b2)-(4*a2*c2));
  2. e2 = (-(b2)+e2)/(2*a2);
  3. f2 = sqrt((b2*b2)-(4*a2*c2));
  4. f2 = (-(b2)-f2)/(2*a2);
  5.  

no existe raiz cuadrada de numeros negativos, daria un numero imaginario.
a parte para que funcione deberia verse como esto:

Código
  1. e2= ((b2*b2)(-4*(a2*c2))); //aca puse bien la distribucion de la ecuacion.
  2. if (e2>0){
  3. e2=(sqrt(e2))/(2*2a);
  4. }
  5. else{
  6. printf("No existe raiz 1.");}

y haces lo mismo con la de abajo. Fijate que en c te va a devolver un numero como 1.00#EI000 o algo asi (si es un float).


Lh: No hagas doble post, utiliza el botón modificar.

Si te interesa yo publique mi codigo de un programa C que resuelve funciones polinomicas y racionales:

http://foro.elhacker.net/programacion_cc/funciones_polinomicas_y_racionales-t303016.0.html (http://foro.elhacker.net/programacion_cc/funciones_polinomicas_y_racionales-t303016.0.html)


Título: Re: Novato en C...
Publicado por: andres_5 en 26 Agosto 2010, 15:49 pm
Como pude haber fallado en eso XD.
muchas Gracias. por ahora via intentar hacerlo con mi propios medios..., si tengo alguna duda miro tu programa ;)

Lh: No hagas doble post, utiliza el botón modificar.

Me tira el mismo error.
Codigo resultante es:
Código:
//llamos a las librerias necesarias.
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
// datar las variable.
int a, b, c, d, e, f;
int a2, b2, c2, d2, e2, f2;
char a1, b1, c1;
//EMPEZAMOS
int main(int argc, char** argv)
{
//Creamos numeros aleatorio.
crear:
srand (time(NULL));
a = rand()%9;
b = rand()%21;
c = rand()%21;
d = rand()%21;
//creamos los numeros negativos
a=a-4;
b=b-10;
c=c-10;
d=d-10;
//Administramos los signo de la ecuacion.
if (a > 0)
{ a1= '+';}
else{a1=' ';}

if (b > 0)
{b1= '+';}
else{b1=' ';}

if (c > 0)
{c1= '+';}
else{c1=' ';}
//Creamos variables secundarias para poder operar comodamente con ellas.
a2 = a;
b2 = b;
c2 = c;
d2 = d;
//Operamos...
c2 = c2 - d2;
e2= ((b2*b2)+(-4*(a2*c2)));
if (e2>=0){
if (a2!=0){
e2=(sqrt(e2))/(2*2*a2);}
else
{ goto crear;
}
}else{
goto crear;
}

f2= ((b2*b2)+(-4*(a2*c2)));
if (f2>=0){
if (a2!=0){
f2=(sqrt(f2))/(2*2*a2);
}
}
else{
goto crear;
}

//Presenta la ecuacion con los requisitos aprovados, osea con soluciones reales y enteros.
printf ("%c%dx²%c%dx%c%d=%d \n", a1, a, b1, b, c1, c, d);

return 0;
}
sale el mismo error que antes.
saludos y gracias de antemano.