Aprendiendo Programación: Recursividad 2ª parte
Publicado el 24 de enero de 2008Gracias al aporte en los comentarios corregí un poco el código y el post sobre recursividad. Obviamente, después de leer los comentarios, a la noche llegué a casa y a programar!
En el código, la función factorial cambia, en vez de devolver un entero sin signo, devuelve un float para evitar la limitación hasta 12.
También el (while n=!1), lo usé porque creo que queda más claro la condición, Pero se puede hacer más fácil todavía con if n!=1:
float factorial(unsigned long n){ if (n!=1) return (n * factorial(n-1)); return 1; } |
Especificadores de formato
Cuando se usa printf en C para imprimir valores en pantalla, cada tipo de variable tiene un especificador de formato. Como estaba intentando mostrar un entero sin signo con el especificador de entero simple, no llegaba a la capacidad del resultado.
Junté entre libros e internet, una tabla de especificadores de formatos permitidos por printf():
Especificador de formato | Tipo de variable | Cómo se muestra |
%d – %i | int (entero) | decimal (base 10) |
%D – %ld | long (entero) | decimal (base 10) |
%o | unsigned int (entero sin signo) | octal (base 8 ) |
%O – %lo | unsigned long (entero largo sin signo) | octal (base 8 ) |
%u | unsigned int (entero sin signo) | decimal (base 10) |
%U – %lu | unsigned long (entero largo sin signo) | decimal (base 10) |
%x – %X | unsigned int (entero sin signo) | hexadecimal (base 16 ) |
%f – %F | float – double | punto flotante sin exponente |
%e – %E | float – double | Notación científica con e(E) |
%g – %G | float – double | Usa exponente (notación científica) si es necesario |
%a – %A | float – double | hexadecimal (base 16 ) punto flotante |
%c | int – char | Caracter |
%s | array de char’s | Cadena de caracteres |
%p | puntero | Dirección en hexadecimal |
%lf | double | Punto flotante |
%LF | double long | Punto flotante |
El código nuevo arreglado:
Factorial en C
Lo que cambió fue la función factorial, a como la escribí más arriba, y en el main(), cuando muestra el resultado, cambié el especificador de formato a %g, para que muestre con exponente cuando sea necesario:
printf("%g \n", factorial(numero));
Así, al ingresar por ejemplo:
fernando@nando-debian:~/blog/recursividad$ ./factorial 6
Muestra:
El factorial de 6 es: 720
Y al ingresar:
fernando@nando-debian:~/blog/recursividad$ ./factorial 15
Muestra:
El factorial de 15 es: 1.30767e+12
Comprobado científicamente que los resultados están bien (con la calculadora científica).
La idea de todo éste tipo de posts es de repente meter todo en un wiki, para así poder ir corrigiendo los errores y detalles como ahora. Pero eso para más adelante, por ahora no hay tiempo.
5 comentarios en este post
Feed de comentarios-
Aprendiendo programación: Recursividad | Picando Código |
13 julio. 2008 - 15:59
[…] artículo fue actualizado en: Aprendiendo programación: recursividad 2ª parte A continuación el código fuente de un programita que recibe un número como parámetro, y […]
fernando 24 enero. 2008 - 15:58
Pablo me hizo notar, que en la función factorial dejé afuera el cero, por lo que si el parámetro ingresado es 0, está todo mal… Habría que poner en la condición if (n!=1 || n!=0)
Fabián Arenas L.. 24 enero. 2008 - 22:55
int main(int cantArg, char *argv[]…. y esto pa que era, a mi cuando me enseñaron me dijero que era int main(int argc, char **argv )
Ahora, veo que usas itoa, no te lo recomiendo, estas funciones no son de gcc, ( en algunos trabajos o S.O no podras usar estas funciones sin su respectiava Biblioteca ), crea mejor una funcion que retorne el valor por ejemplo para transformar un string en un numero, no con una libreria…..
por lo demas el codigo lo encontre bueno, eso si que en vez de usar los unsigned, yo hubiera hecho un if( n<=0 )…. y en el printf poner el signo altiro….
Saludos
daniel 26 enero. 2008 - 00:50
Solo queria comentar, que escribir funciones recursivas en un lenguaje como C no es muy recomendable en cuanto a performance, siempre que una funcion recusiva se pueda escribir como un loop es mejor escribir el loop.
En lenguajes de mas alto nivel (sobre todo en lenguajes funcionales) el compilador intenta hacer ese trabajo por nosotros asi que no hay problema. De todos modos el gcc (calculo que otros compiladores de C tambien) trae una flag “-foptimize-sibling-calls” para tail call optimization.
saludos
Carlos 24 marzo. 2008 - 20:47
En verdad,se que hace mucho que hiciste el post, pero, buscando “como aplicar la recursividad” lo encontre y me gusto bastante. El tema es, que aunque tampoco soy experto, creoo que quizas, deberias sustituir el “float” por un “unsigned long” osea:
unsigned long factorial(unsigned long n) {
…
}
Asi, a mi me responde apropiadamente (Como entero) hasta el 16 que es: 2004189184.
No he comprobado si esto es cierto, pero no veo razon para que no lo sea, sin embargo, despues lo investigo : )
Saludos