Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: jairogon en 1 Julio 2010, 03:52 am



Título: Calcular mcd. Compila bien pero no corre
Publicado por: jairogon en 1 Julio 2010, 03:52 am
El siguiente programa compila bien pero no corre, la verdad no se por que?


Uso el DevC++.


Código:
//Programa que calcula el m.c.d de dos numeros
//enteros positivos.
#include<iostream>
#include<conio2.h>

using namespace std;

int main()
{
  int a=0,b=0,mayor=0, menor=0,residuo=0,divisor=0,dividendo=0,resultado=0,mcd=0;
   cout<<"Entra dos numeros enteros: ";
    cin>>a>>b;

     if(a>=b)
     {
       mayor=a;
       menor=b;
     }else
          {
            mayor=b;
            menor=a;
          }
           dividendo=menor;
           divisor=mayor;

             do{
                 resultado=divisor/dividendo;
                  residuo=divisor%dividendo;
                   divisor=dividendo;
                    dividendo=residuo;
               }while(dividendo==0||residuo==0);

     mcd=dividendo;

     if(mcd==1)
     {
       cout<<"Los numeros :"<<a<<" y"<<b<<" son primos entre si pues el mcd es 1";
     } else
           {
             cout<<"El mcd de "<<a<<" y"<<b<<" es: "<<mcd;
           }

   getche();
  
   return 0;

}


Título: Re: Compila bien y no corre
Publicado por: cbug en 1 Julio 2010, 04:23 am
Preferiría que utilices un system call antes que un getche de conio2.

Si compila bien, no queda otra que depurarlo.


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 1 Julio 2010, 04:53 am
jairogon, te dejo esta funcion que seguro te sirve...

Código:
int mcd( int a, int b ) 
{
    a = abs( a );
    b = abs( b );
    if ( b == 0 )
        return a;
    else
        return mcd( b, a % b );
}

Nota: codigo corregido en base a lo planteado por do-while

Salu10.


Título: Re: Compila bien y no corre
Publicado por: jairogon en 1 Julio 2010, 05:38 am
jairogon, te dejo esta funcion que seguro te sirve...

Código:
int mcd( int a, int b ) 
{
    if ( b == 0 )
        return a;
    else
        return mcd( b, a % b );
}

Salu10.


Gracias

Vaya que si me sirvio.

No sabia que el mcd se pudiera hallar recursivamente.

De nuevo mil Gracias

 :D ;-)


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 1 Julio 2010, 05:59 am
jairogon, de nada! Para eso estamos ;)

Salu10.


Título: Re: Compila bien y no corre
Publicado por: MIG80 en 1 Julio 2010, 06:26 am
Tu programa original tambien funciona con unos pequeños ajustes:

Código
  1. //Programa que calcula el m.c.d de dos numeros
  2. //enteros positivos.
  3. #include<iostream>
  4. #include<conio2.h>
  5.  
  6. using namespace std;
  7.  
  8. int main()
  9. {
  10.  int a,b,mayor, menor,residuo,divisor,dividendo,resultado,mcd;
  11.  cout<<"Entra dos numeros enteros: ";
  12.  cin>>a>>b;
  13.  
  14.  if(a>=b)
  15.  {
  16.    mayor=a;
  17.    menor=b;
  18.  }else
  19.  {
  20.    mayor=b;
  21.    menor=a;
  22.  }
  23.  dividendo=mayor; // se llama "dividendo" al numero que sera dividido
  24.  divisor=menor;    // se llama "divisor" al numero que divide
  25.  
  26.  do{
  27.    resultado=dividendo/divisor;
  28.    residuo=dividendo%divisor;
  29.    dividendo=divisor;
  30.    divisor=residuo;
  31.  }while(divisor!=0);
  32.  
  33.  mcd=dividendo;
  34.  
  35.  if(mcd==1)
  36.  {
  37.    cout<<"Los numeros :"<<a<<" y "<<b<<" son primos entre si pues el mcd es 1";
  38.  } else
  39.  {
  40.    cout<<"El mcd de "<<a<<" y "<<b<<" es: "<<mcd;
  41.  }
  42.  
  43.  getche();
  44.  
  45.  return 0;
  46. }
  47.  


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 1 Julio 2010, 07:28 am
Tu programa original tambien funciona con unos pequeños ajustes:

Código
  1. //Programa que calcula el m.c.d de dos numeros
  2. //enteros positivos.
  3. #include<iostream>
  4. #include<conio2.h>
  5.  
  6. using namespace std;
  7.  
  8. int main()
  9. {
  10.  int a,b,mayor, menor,residuo,divisor,dividendo,resultado,mcd;
  11.  cout<<"Entra dos numeros enteros: ";
  12.  cin>>a>>b;
  13.  
  14.  if(a>=b)
  15.  {
  16.    mayor=a;
  17.    menor=b;
  18.  }else
  19.  {
  20.    mayor=b;
  21.    menor=a;
  22.  }
  23.  dividendo=mayor; // se llama "dividendo" al numero que sera dividido
  24.  divisor=menor;    // se llama "divisor" al numero que divide
  25.  
  26.  do{
  27.    resultado=dividendo/divisor;
  28.    residuo=dividendo%divisor;
  29.    dividendo=divisor;
  30.    divisor=residuo;
  31.  }while(divisor!=0);
  32.  
  33.  mcd=dividendo;
  34.  
  35.  if(mcd==1)
  36.  {
  37.    cout<<"Los numeros :"<<a<<" y "<<b<<" son primos entre si pues el mcd es 1";
  38.  } else
  39.  {
  40.    cout<<"El mcd de "<<a<<" y "<<b<<" es: "<<mcd;
  41.  }
  42.  
  43.  getche();
  44.  
  45.  return 0;
  46. }
  47.  

czealt, tu codigo tiene algunos errores, por ejemplo la division por 0 no es valida.

Esta linea no la utilizas resultado = dividendo / divisor;

Ademas como bien menciono cbug, no es recomendable el uso de la libreria conio ya que no es estandar y esta obsoleta.

Aca dejo un codigo parecido al que venia haciendo jairogon

Código:
#include <iostream>
#include <cmath>

using namespace std;

int main( void )
{
    int a, b, mayor, menor, residuo, divisor, dividendo, mcd;

    cout << "Entra dos numeros enteros: ";
    cin >> a >> b;

    a = abs( a );
    b = abs( b );
    if ( a >= b )
    {
        mayor = a;
        menor = b;
    }
    else
    {
        mayor = b;
        menor = a;
    }
    dividendo = mayor;
    divisor = menor;
    
    while ( divisor != 0 )
    {
        residuo = dividendo % divisor;
        dividendo = divisor;
        divisor = residuo;
    }
    
    mcd = dividendo;

    if ( mcd == 1 )
        cout << "Los numeros " << a << " y " << b << " son primos entre si pues el m.c.d es 1" << endl;
    else
        cout << "El m.c.d de " << a << " y " << b << " es: " << mcd << endl;
    
    return 0;
}

Nota: codigo corregido en base a lo planteado por do-while

Salu10.


Título: Re: Compila bien y no corre
Publicado por: MIG80 en 1 Julio 2010, 19:31 pm
nicolas_cof, tienes razón en que la variable resultado no es necesaria. En lo del bucle (en tu version del  programa)..., da lo mismo si es while o do..while. Como  quitaste la linea resultado=dividendo/divisor; ya no existe la posibilidad de una división por 0.


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 1 Julio 2010, 21:21 pm
nicolas_cof, tienes razón en que la variable resultado no es necesaria. En lo del bucle (en tu version del  programa)..., da lo mismo si es while o do..while. Como  quitaste la linea resultado=dividendo/divisor; ya no existe la posibilidad de una división por 0.

czealt, si te fijas bien en el codigo no seria lo mismo hacer un while que un do-while ya que con este ultimo estarias ejecutando 3 sentencias totalmente innecesarias.

Salu10.


Título: Re: Compila bien y no corre
Publicado por: MIG80 en 1 Julio 2010, 21:28 pm
Citar
... si te fijas bien en el codigo no seria lo mismo hacer un while que un do-while ya que con este ultimo estarias ejecutando 3 sentencias totalmente innecesarias.

Bueno, eso solo sucederia cuando uno de los números dados como entrada es cero lo cual no es una entrada válida para el programa. Si se ha de verificar por la entrada válida, ¿porqué no tambien verificar por la entrada de números negativos?


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 1 Julio 2010, 22:41 pm
Citar
... si te fijas bien en el codigo no seria lo mismo hacer un while que un do-while ya que con este ultimo estarias ejecutando 3 sentencias totalmente innecesarias.

Bueno, eso solo sucederia cuando uno de los números dados como entrada es cero lo cual no es una entrada válida para el programa. Si se ha de verificar por la entrada válida, ¿porqué no tambien verificar por la entrada de números negativos?

czealt, porque pensas que se tendria que verificar por la entrada de numeros negativos?

Citar
El máximo común divisor (abreviado mcd o m.c.d.) de dos o más números enteros es el mayor número que los divide sin dejar resto. - Wikipedia

Que se ingrese como entrada el valor 0, no quiere decir que este sea una entrada invalida para el programa, ya que por definicion seria correcto. Yo lo que te queria decir con respecto del do-while es que ejecutarias 3 sentencias totalmente innecesarias que no aportan ningun valor al objetivo del programa. Por eso es mejor usar el while y evitar ejecutar ese bloque de codigo.

Salu10.


Título: Re: Compila bien y no corre
Publicado por: MIG80 en 2 Julio 2010, 00:00 am
OK nicolas_cof si 0 es un valor válido como entrada para el programa que calcula el M.C.D de dos números dime cuanto es el MCD de 0 y 1?


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 2 Julio 2010, 00:09 am
OK nicolas_cof si 0 es un valor válido como entrada para el programa que calcula el M.C.D de dos números dime cuanto es el MCD de 0 y 1?

1

Salu10.


Título: Re: Compila bien y no corre
Publicado por: MIG80 en 2 Julio 2010, 00:35 am
Muy bien (señido a la definición, como debe de ser).

Saludos.


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 2 Julio 2010, 01:10 am
Muy bien (señido a la definición, como debe de ser).

Saludos.

Código:
function mcd(a, b)
    while b ≠ 0
       t := b
       b := a mod b
       a := t
    return a

Salu10.


Título: Re: Compila bien y no corre
Publicado por: do-while en 2 Julio 2010, 01:48 am
¡Buenas!

Solo un apunte y no con intencion de faltar a nadie, simplemente con la de informar.

El mcd de dos enteros (d a partir de ahora) a y b, cumple que si c|a y c|b entonces d|c. En estas condiciones se encuentran dos numeros enteros, d y -d.

Para evitar confusiones y por la unicidad de los resultados, se llama mcd(a,b) a max{d,-d}, es decir, al que es positivo.

Otra propiedad del mcd es que mcd(a,b) = mcd (|a|,|b|), por lo que para obtener el mcd de dos enteros por medio del algoritmo de euclides, al trabajar con ordenadores, lo correcto seria trabajar con el valor absoluto de los datos introducidos, ya que de esta forma obtendremos directamente el valor positivo.

Otro apunte es que para calcular el mcd por medio del algoritmo de auclides, se utiliza la division euclidea que dice que dados dos enteros a y b, existen otros dos enteros, unicos, c y r cumpliendo que:

a = cb + r    donde    0 <= r < |b|

Es decir, el resto es positivo, y esto es algo que en C/C++ no se cumple al calcular modulos, ya que si el dividendo y el divisor tienen signos opuestos a%b dara como resultado un entero negativo.

¡Saludos!


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 2 Julio 2010, 01:56 am
Cita de: do-while
... lo correcto seria trabajar con el valor absoluto de los datos introducidos ...

Tenes razon do-while, esto ultimo se me habia pasado por alto! Gracias ;)

Salu10.


Título: Re: Compila bien y no corre
Publicado por: do-while en 2 Julio 2010, 01:59 am
¡De nada!

Todo el mundo tiene algun patinazo de vez en cuando, servidor incluido  :silbar:, faltaria mas.

¡Saludos!


Título: Re: Compila bien y no corre
Publicado por: cbug en 2 Julio 2010, 02:36 am
Podría ser esta una solución rápida, me basé en teoremas de congruencias:

Código
  1. #include <stdio.h>
  2.  
  3. int mcd(int a, int b)
  4. {
  5.  if(b == 0)
  6.    return a;
  7.  else
  8.    mcd(a, a%b);
  9. }
  10.  
  11. void _abs(int *a)
  12. {
  13.  if(*a < 0) *a *= -1;
  14. }
  15.  
  16. int main()
  17. {
  18.  int x, y, mxdiv;
  19.  scanf("%d %d", &x, &y);
  20.  _abs(&x);
  21.  _abs(&y);
  22.  printf("\t %d \t %d", x, y);
  23.  mxdiv = mcd(x, y);
  24.  printf("\n MCD > %d \n", mxdiv);
  25.  return 0;
  26. }

Lei que también el operador condicional ? sería un buen reemplazo para ese if de _asb.


Título: Re: Compila bien y no corre
Publicado por: nicolas_cof en 2 Julio 2010, 20:29 pm
cbug, fijate en esta parte...

Código:
int mcd( int a, int b )
{
  if ( b == 0 )
    return a;
  else
    mcd( b, a % b ); //mcd( a, a % b );
}

Yo usaria la funcion abs() dentro de la funcion mcd(), debido a lo que habia aclarado do-while, que a mi se me habia pasado por alto. Ya que haciendo esto uno se olvida de tener que aplicarle el valor absoluto a los numeros antes de pasarlos a la funcion mcd().

Otro punto que se podria ver, seria usar la funcion abs() de la libreria stdlib.h

Código:
#include <stdio.h>
#include <stdlib.h>
 
int mcd( int a, int b )
{
    a = abs( a );
    b = abs( b );
    return ( b == 0 ) ? a : mcd( b, a % b );
}
 
int main( void )
{
    int x, y;
    scanf( "%d %d", &x, &y );
    printf( "mcd: %d\n", mcd( x, y ) );
    return 0;
}

Salu10.


Título: Re: Calcular mcd. Compila bien pero no corre
Publicado por: do-while en 2 Julio 2010, 22:35 pm
¡Buenas!

Eso es nicolas_cof. Lo crrecto seria mcd(b,a%b); no mcd(a,a%b); ya que mcd{a,b} = mcd{b,r}, con r el resto de dividir a por b (es decir |a|%|b|).


Título: Re: Calcular mcd. Compila bien pero no corre
Publicado por: cbug en 3 Julio 2010, 01:22 am
Código:
 mcd( b, a % b ); //mcd( a, a % b );

Eso fue una corrección? Creo que ya fue respondida por do-while.  :xD

Ahora bien, lo de incluir stdlib.h para usar abs(), me parece mucho, no sé si en esto último estoy en lo correcto.


Título: Re: Calcular mcd. Compila bien pero no corre
Publicado por: nicolas_cof en 3 Julio 2010, 02:47 am
Código:
 mcd( b, a % b ); //mcd( a, a % b );

Eso fue una corrección? Creo que ya fue respondida por do-while.  :xD

Si, fue una correcion, que ya fue afirmada por do-while. ;)

Código:
 mcd( b, a % b ); //mcd( a, a % b );
Ahora bien, lo de incluir stdlib.h para usar abs(), me parece mucho, no sé si en esto último estoy en lo correcto.

cbug, al contrario ya que en la etapa de enlazado se extrae solamente la funcion utilizada de la libreria stdlib.h, en este caso abs().

Ademas si te pones a comparar entre el codigo generado en asm usando una funcion propia _abs() y la que viene en la libreria stdlib.h, la diferencia es bastante notable y favorable para la funcion abs() y por ende mucho mas eficiente.

Salu10.


Título: Re: Calcular mcd. Compila bien pero no corre
Publicado por: cbug en 3 Julio 2010, 03:06 am
 :-[ Ups es cierto xD.

Ahora bien, gracias por el consejo sobre la librería... no sabía que en el enlazado sólo se extrae esa función.


Título: Re: Calcular mcd. Compila bien pero no corre
Publicado por: nicolas_cof en 3 Julio 2010, 03:09 am
cbug, de nada! Para eso estamos compañero ;)

Salu10.