Implementar o cálculo do fatorial (!) de um número, lançando mão da estratégia de recursão, é a forma mais compacta e interessante que conhecemos, explorando conceitos matemáticos (produtório) e de software (pilha, operadores de atribuição compostos e recursão em si).
(texto complementar longo, não leia se não precisar)
Caso se aventure no assunto relacionado a fatoriais, há também o duplo fatorial (!!) e, como curiosidade, há fatorial cujo argumento recebe números decimais. E números negativos?
Atenção
Um ponto relevante quando se lida com fatoriais, por exemplo, diz respeito ao tipo empregado para armazenar os fatores. Tenha em mente qual a capacidade do tipo int
empregado no seu código (4, 8, 16 bytes) e se o mesmo pode manter todos os valores da mantissa sem prejudicar a precisão exigida pela sua aplicação! Limitações do tipo da variável podem produzir resultados inesperados em determinadas situações (Ex.: 17! = -288522240 overflow). Se a resposta é dada em notação científica, é uma mera representação do resultado da operação realizada com os tipos envolvidos e suas limitações.
Otimização
Dependendo do número de chamadas de sua função fatorial, vale a pena pensar manter uma lookup table (LUT) em memória, calculada uma única vez para os valores mais recorrentes, já que são constantes. É uma outra forma de recuperar o fatorial de um número. Quando ciclos de máquina for um fator crítico, LUT pode ser uma solução, claro, com custos do consumo de memória. Cada caso é um caso! Por exemplo, a expansão de função em série de Taylor emprega fatoriais muito frequentemente, principalmente o seu valor recíproco, 1/fat(x). Valeria a pena armazenar esses valores recíprocos, não? : )
Um pouco mais sobre LUTs
lookup tables são úteis, em certos casos, quando observa-se que é mais eficiente recuperar um valor constante pré-calculado comparado ao número de ciclos que seriam necessários para invocar e executar determinada função. No caso de fatoriais (ou seus valores recíprocos), uma lista poderia ser calculada a priori usando alguma ferramenta adequada.
Curiosidade
Quando alta precisão é um requisito, uma ferramenta que adota, por exemplo, aritmética de precisão arbitrária (BC, Maxima etc.) é bastante útil para evitar os erros de arredondamento ao máximo, com um certo custo computacional. A ferramenta de linha de comando Linux bc
pode ser utilizada para resolver, praticamente, qualquer fatorial sem perda de precisão, afinal é uma multiplicação de fatores inteiros. Aqui há uma lista para os 100 primeiros fatoriais de uma lista. Outros valores podem ser calculados com a linha de código seguinte, bastante simplificada, válida somente para números inteiros positivos. Consome cerca de 5 segundos para calcular o fatorial de 20000 num PC...:
export BC_LINE_LENGTH=9999; echo "define f(n){if(n<2)return(1);return(n*f(n-1))};f(100)" | bc -l