hola nakamas como estan?, espero que bien, necesitaría ayuda, me piden que cree una función recursiva que determine si un numero es positivo o no, es un caso de recursividad cruzada, casi seguro que tengo un error conceptual en mi problema, mi duda està en que en c no puedo usar public boolean(con false y true), e hice esto, pero obviamente no compila:
y tengo otra, se puede crear una tercer funcion para que solamente llame a esa sola?
#include <stdlib.h>
#include <string.h>
int negativo(int n);
int positivo(int n);
int main()
{
int N;
printf("ingrese el numero\n");
scanf("%d",&N);
positivo(N);
negativo(N);
return 0;
}
int positivo(int n)
{
if(n>=0)
{
printf("el numero ingresado es positivo");
}
else
{
return negativo(n);
}
}
int negativo(int n)
{
if(n<0)
{
return n;
printf("el numero ingresado es nevativo");
}
else
{
return positivo(n);
}
}
- Que valor retorna la funcion positivo si el valor que recibe como parametro es efectivamente positivo?
- Sugiero que las funciones positivo y negativo retornen 1 o 0.
- Sugiero que no hagas ningun printf al interior de esas funciones, sino que sea el main el que lo haga basado en el valor que esas funciones retornen.
Si pudieras especificar un poco más tu problema... Es decir, ese programa compilar, compila (si le añades la librería <stdio.h> para poder usar <scanf()> y <printf()>). Además puedes quitar <stdlib.h> y <string.h> ya que no estás usándolo para nada en todo el programa.
De todos modos ese programa sigue teniendo errores (aunque ya compila). Si llamas a <positivo(n)> con n positivo, sale el mensaje por pantalla "el numero ingresado es positivo" pero no has hecho ningún <return> (creo que entonces se retorna n pero es mejor especificarlo en el código para que quede explícito).
Si llamas a <negativo(n)> con n negativo, la función retorna n, pero no se mostrará por pantalla "el numero ingresado es nevativo" (creo que querías poner "neGativo" :xD) porque una vez que una función ejecuta un <return> ya sale de la función y no se ejecuta lo que venga después.
Por eso que no se muy bien cual es el fin de esa función, si quieres retornar el mismo número que mandas como parámetro o quieres retornar 1 o 0 como si fuese true o false respectivamente... Y sí, si quieres crear otra función que llame a una de esas puedes hacerlo, pero lo veo un poco absurdo todo esto porque son dos funciones muy sencillas. Algo más funcional sería:
int positivo(int n){
return (n >= 0);
}
Que devuelve 1 si es positivo y 0 si es negativo. De que sirve crear una función <negativo()> si <negativo() == !positivo()>??
Hola gracias a los dos por las respuestas, ajaja si creo que la RAE todavia no modifico el negativo a nevativo, en realidad el enunciado del problema dice cree un algoritmo recursivo que diga si un numero ingresado es negativo o positivo, ya c que suena tonto, pero buscando por internet vi que lo resuelven con recursividad cruzada, pero usan una sentencia que dice public boolean y retornan un true o un false, pero eso estaba resuelto en java
0 es considerado false, diferente a 0 es considerado true.
Pero a partir de C99 hicieron la librería stdbool que sirve para manejar true y false.
graciass
Me gustó el problema y supongo que ya lo tienes solucionado, así que me he dispuesto a dar solución recursiva a ello. Poco eficiente pero recursiva. Usa una función de interface:
#include <stdio.h>
int f1(unsigned long n, unsigned long long s) {
return s==1? n : f1(n>>1, --s);
}
int es_negativo(unsigned long n) {
return f1(n, sizeof(unsigned long long)*8);
}
int main() {
printf("%d\n", es_negativo(65536));
printf("%d\n", es_negativo(-32));
}
Mafus gracias,se nota que sabes programar avanzado pero es demasiado eso para mi, ajaajaj, hace de cuenta que le estas enseñando a un cavernicola, porque usas sizeof?, y que significa --s?
tampoco entiendo porque le pasas como parametro n>>1
tu codigo para super pro, a mi al final me quedo esto estaria bien?
int negativo(int n);
int positivo(int n);
int main()
{
int N;
printf("ingrese el numero\n");
scanf("%d",&N);
positivo(N);
negativo(N);
return 0;
}
int positivo(int n)
{
if(n>=0)
{
return 1;
}
else
{
printf("el numero es negativo\n");
return negativo(n);
}
}
int negativo(int n)
{
if(n<0)
{
return 0;
}
else
{
printf("el numero es positivo\n");
return positivo(n);
}
}
¿Os ensenan recursividad sin haber pasado todavía por todos los operadores?
Qué curioso.
Cita de: fernaEDLP en 13 Enero 2019, 07:43 AM
Mafus gracias,se nota que sabes programar avanzado pero es demasiado eso para mi, ajaajaj, hace de cuenta que le estas enseñando a un cavernicola, porque usas sizeof?, y que significa --s?
Aunque ya tengas el tema solucionado, lo importante es resolver las dudas que quedan así que...
- <sizeof()> se usa para obtener el número de bytes que ocupa un tipo de dato. En ese código te devuelve el número de bytes que ocupa un <unsigned long long>.
- <--s> significa decrementar <s> en 1. Al igual que se suele hacer <i++>, se puede hacer también <i-->, <++i> o <--i>. A veces da igual usar el prefijo o el sufijo (cuando es una sentencia aislada, que no va como "encadenada"). El prefijo primero hace el incremento/decremento y después el resto de la sentencia; el sufijo primero hace el resto de la sentencia y al final hace el incremento/decremento.
for(int i = 0; i < 5; i++) // aqui da igual i++ o ++i porque esta solo
printf("%d", i++); // primero muestra i y luego lo incrementa en 1. Salida: 0, 2, 4
for(int i = 0; i < 5; i++)
printf("%d", ++i); // incrementa i y luego lo muestra. Salida: 1, 3, 5 (el 5 se muestra aunque la condicion es i < 5)
Cita de: fernaEDLP en 13 Enero 2019, 07:48 AM
tampoco entiendo porque le pasas como parametro n>>1
Si haces <num >> 1> lo que haces es mover los bits de <num> una posición a la derecha. Si tienes:
a = 01011001
a >> 1
a = 00101100
Si el número es negativo se extiende con unos:
a = 11010011
a >> 1
a = 11101001
Como dato interesante que si no te paras a estudiar los bits no te das cuenta es que mover una posición a la izquierda un número en binario es equivalente a multiplicar ese número por 2. Y entonces moverlo una posición a la derecha es equivalente a dividirlo por 2, aunque si es impar se hará obviando los decimales.
Entonces para que entiendas el código ese que la verdad aunque poco efectivo, me parece impresionante:
Usa una función donde manda un <unsigned long long> que es el número a calcular y le pasa como segundo parámetro el número de bits que ocupa un número <unsigned long long> (con <sizeof()> saca el número de bytes y eso por 8, en bits).
Entonces cuando <s == 1> es decir, cuando sólo quede el bit más significativo se retorna ese bit (que valdrá 1 si el número es negativo o 0 si no lo es). Y si <s != 1>, mueve todos los bits una posición a la derecha y decrementa el número de bits que quedan todavía. Algo así en un caso simplificado:
n = 4 (0100) s = 4
s == 1? No -> n = 2 (0010) s = 3
s == 1? No -> n = 1 (0001) s = 2
s == 1? No -> n = 0 (0000) s = 1
s == 1? Si -> return n (return 0)
n = -2 (1110) s = 4
s == 1? No -> n = -1 (1111) s = 3 // los negativos se extienden con 1 para que sigan siendo negativos (cosas del complemento a 2)
s == 1? No -> n = -1 (1111) s = 2
s == 1? No -> n = -1 (1111) s = 1
s == 1? Si -> return n (return 1)
Una función de ese estilo es mejor que no muestre nada por pantalla por si quieres usar esa función dentro de un condicional, sería más funcional entonces sin los <printf()>:
int positivo(int n){
if(n >= 0)
return 1;
else
return !negativo(n);
}
int negativo(int n){
if(n < 0)
return 1;
else
return !positivo(n);
}
Espero que esto te ayude a entender y profundizar más en todo lo que se puede hacer con la programación. Suerte :-X
perdón creo que puse cualquier cosa ahí arriba, ahora creo que esta bien, igual es como muy secillo
void negativo(int n);
void positivo(int n);
int main()
{
int N;
printf("ingrese el numero\n");
scanf("%d",&N);
positivo(N);
return 0;
}
void positivo(int n)
{
if(n>=0)
{
printf("el numero es positivo\n");
}
else
{
negativo(n);
}
}
void negativo(int n)
{
if(n<0)
{
printf("el numero es negativo\n");
}
else
{
positivo(n);
}
}
perdon no habia entrado a la segunda pagina
Cita de: YreX-DwX en 13 Enero 2019, 11:11 AM
Aunque ya tengas el tema solucionado, lo importante es resolver las dudas que quedan así que...
- <sizeof()> se usa para obtener el número de bytes que ocupa un tipo de dato. En ese código te devuelve el número de bytes que ocupa un <unsigned long long>.
- <--s> significa decrementar <s> en 1. Al igual que se suele hacer <i++>, se puede hacer también <i-->, <++i> o <--i>. A veces da igual usar el prefijo o el sufijo (cuando es una sentencia aislada, que no va como "encadenada"). El prefijo primero hace el incremento/decremento y después el resto de la sentencia; el sufijo primero hace el resto de la sentencia y al final hace el incremento/decremento.
for(int i = 0; i < 5; i++) // aqui da igual i++ o ++i porque esta solo
printf("%d", i++); // primero muestra i y luego lo incrementa en 1. Salida: 0, 2, 4
for(int i = 0; i < 5; i++)
printf("%d", ++i); // incrementa i y luego lo muestra. Salida: 1, 3, 5 (el 5 se muestra aunque la condicion es i < 5)
Si haces <num >> 1> lo que haces es mover los bits de <num> una posición a la derecha. Si tienes:
a = 01011001
a >> 1
a = 00101100
Si el número es negativo se extiende con unos:
a = 11010011
a >> 1
a = 11101001
Como dato interesante que si no te paras a estudiar los bits no te das cuenta es que mover una posición a la izquierda un número en binario es equivalente a multiplicar ese número por 2. Y entonces moverlo una posición a la derecha es equivalente a dividirlo por 2, aunque si es impar se hará obviando los decimales.
Entonces para que entiendas el código ese que la verdad aunque poco efectivo, me parece impresionante:
Usa una función donde manda un <unsigned long long> que es el número a calcular y le pasa como segundo parámetro el número de bits que ocupa un número <unsigned long long> (con <sizeof()> saca el número de bytes y eso por 8, en bits).
Entonces cuando <s == 1> es decir, cuando sólo quede el bit más significativo se retorna ese bit (que valdrá 1 si el número es negativo o 0 si no lo es). Y si <s != 1>, mueve todos los bits una posición a la derecha y decrementa el número de bits que quedan todavía. Algo así en un caso simplificado:
n = 4 (0100) s = 4
s == 1? No -> n = 2 (0010) s = 3
s == 1? No -> n = 1 (0001) s = 2
s == 1? No -> n = 0 (0000) s = 1
s == 1? Si -> return n (return 0)
n = -2 (1110) s = 4
s == 1? No -> n = -1 (1111) s = 3 // los negativos se extienden con 1 para que sigan siendo negativos (cosas del complemento a 2)
s == 1? No -> n = -1 (1111) s = 2
s == 1? No -> n = -1 (1111) s = 1
s == 1? Si -> return n (return 1)
Una función de ese estilo es mejor que no muestre nada por pantalla por si quieres usar esa función dentro de un condicional, sería más funcional entonces sin los <printf()>:
int positivo(int n){
if(n >= 0)
return 1;
else
return !negativo(n);
}
int negativo(int n){
if(n < 0)
return 1;
else
return !positivo(n);
}
Espero que esto te ayude a entender y profundizar más en todo lo que se puede hacer con la programación. Suerte :-X
graciassss aja!, que lindo paseo me pegaron xD
Por favor no se enojen conmigo, tengo una duda que a estas alturas va a ser estupida, pero cuando se retorna un 1 o un 0, dependiendo de si el usuario digita un negativo o un positivo, como te se da cuenta que el numero es positivo o negativo?¿, no seria mejor que al evaluar la condición dentro del if, cuando chequea que es postivo avise mediante un printf que lo que se ingreso es postivo?, tenganme paciencia pliss :-*
Sí, pero esto es una forma de jugar con el lenguaje. Se prueban diferentes algoritmos sobre problemas de solución sencilla. Divertido, a la par que didáctico. Así cuando surjan problemas reales que necesiten de una solución parecida ya se tendrá experiencia para resolverlo.
perfecto gracias a todos!!
Cita de: fernaEDLP en 13 Enero 2019, 20:56 PM
Por favor no se enojen conmigo, tengo una duda que a estas alturas va a ser estupida, pero cuando se retorna un 1 o un 0, dependiendo de si el usuario digita un negativo o un positivo, como te se da cuenta que el numero es positivo o negativo?¿, no seria mejor que al evaluar la condición dentro del if, cuando chequea que es postivo avise mediante un printf que lo que se ingreso es postivo?, tenganme paciencia pliss :-*
En programación, cuando hay dos posibles respuestas (si/no, verdadero/falso, etc) se traduce a una variable booleana (true/false). Las variables booleanas a veces se interpretan mejor como números (true = 1 / false = 0) y esto sirve para tener un abanico más grande de posibilidades para trabajar por ejemplo con condicionales.
El tema de retornar un 0/1 y no usar un <printf()> es por sencillez. Imagina un programa en el que usas esas funciones que has creado:
int main(){
// codigo
if(positivo(n)){
// codigo
}
// codigo
}
Tú necesitas saber si <n> es positivo, pero no hace falta que le avises al usuario. Puede que tengas un programa muy grande donde haces miles de comprobaciones, el usuario no necesita ver cual es el resultado de cada comprobación.
Con el código que te mostré anteriormente puedes aprovechar lo que te he comentado de interpretar 1 = true y 0 = false para usar esas funciones en programas más grandes. Los posibles casos serían:
- n >= 0 -> positivo(n) retorna 1 (true) y negativo(n) retorna 0 (false)
- n < 0 -> positivo(n) retorna 0 (false) y negativo(n) retorna 1 (true)
Por eso por ejemplo en cada función se llama a la otra con el operador de negación(!). Para que los resultados que se obtienen con cada función sean los comentados arriba. Te dejo el código aquí por si quieres comprobarlo:
int positivo(int n){
if(n >= 0)
return 1;
else
return !negativo(n);
}
int negativo(int n){
if(n < 0)
return 1;
else
return !positivo(n);
}