Gracias 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
  1. Avatar

    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)

    Konqueror 3.5 Debian GNU/Linux
  2. Avatar

    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

    Firefox 2.0.0.11 Windows XP
  3. Avatar

    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

    Firefox 2.0.0.8 Mandriva
  4. Avatar

    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

    Firefox 2.0.0.12 Windows XP
  1. WordPress 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 […]

Dejar un comentario

Notificarme los nuevos comentarios por correo electrónico. Tambien puedes suscribirte sin comentar.

Toasty!