Karl Boy Postado Agosto 4, 2022 em 03:21 Compartilhar Postado Agosto 4, 2022 em 03:21 Bom dia/ Boa tarde/ Boa Noite, preciso de uma ajuda com um código. Sou iniciante e não consigo entender um erro no código, estou aprendendo por umas vídeo aulas no youtube e agora estou aprendendo mais sobre funções (mais especificamente funções recursivas). O código já está funcional, mas o meu problema é que não consigo entender um erro (consegui corrigir, mas não entendi o pq dele estar aparecendo), parece que o if afeta o else e consequentemente o resultado final, o código vai estar logo abaixo: #include <stdio.h> int main(void) { int fatorial(int x); int numero, resultado_final; printf("Digite um número:\n"); scanf("%i", &numero); resultado_final = fatorial(numero); printf("O fatorial de %i é igual a %i\n", numero, resultado_final); return 0; } int fatorial(int x){ int resultado; if(x < 0){ /* Nesse caso o resultado sempre vai ser zero, mas se mudar o (x < 0) para (x == 0) o else funciona normalmente, ou seja, o if de alguma forma afeta o else que modifica o resultado final (lembrando que isso é aos meus olhos de iniciante), mas quero saber o pq isso acontece??? Podem me ajudar? Por favor. */ resultado = 1; } else{ resultado = x * fatorial(x - 1); } return resultado; } Minha pergunta é: pq o resultado sempre é zero? Se a condição de if não for falsa, não deveria pular para else e executar normalmente?? 1 Citar Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Agosto 4, 2022 em 19:57 Compartilhar Postado Agosto 4, 2022 em 19:57 (editado) Você sabe que 0*(-1) = 0, né? Editado Agosto 4, 2022 em 19:58 por fredericopissarra 1 Citar Link para o comentário Compartilhar em outros sites More sharing options...
Karl Boy Postado Agosto 5, 2022 em 01:21 Autor Compartilhar Postado Agosto 5, 2022 em 01:21 Você leu que estou começando a aprender sobre funções recursivas, né? Mas, meu problema não é com a matemática e sim com a lógica. Pelo que entendi da sua resposta e o pouco que sei sobre funções recursivas, outras funções são criadas na memória até o calculo chegar a zero e depois ela retorna o resultado, mas como o X só pode ser menor que zero, ela não chega até o final e acaba retornando zero, seria isso o que quis dizer? Poderia me indicar algum post/artigo que possa me ajudar? Por favor. Desde já agradeço. 1 Citar Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Agosto 6, 2022 em 03:01 Compartilhar Postado Agosto 6, 2022 em 03:01 (editado) Considere: int fact( int x ) { if ( x < 0 ) return 1; return x * fact( x - 1 ); } Se x = 0, inicialmente, temos um return 0 * fact( -1 ); E essa chamada, recursiva, retornará 1 (já que o novo x < 0)... Dai, 0 * 1 = 0. Note que, por definição, n! = 1 se n <= 1. E fatorial só é definido para valores positivos... A rotina DEVERIA ser: unsigned int fact( unsigned int x ) { if ( x <= 1 ) return 1; return x * fact( x - 1 ); } Sendo que a função causará overflow se x > 12. Editado Agosto 6, 2022 em 03:02 por fredericopissarra 1 Citar Link para o comentário Compartilhar em outros sites More sharing options...
Karl Boy Postado Agosto 8, 2022 em 02:44 Autor Compartilhar Postado Agosto 8, 2022 em 02:44 Muito Obrigado, Frederico! Consegui entender, você e os "printf" que espalhei por todo o código me fizeram entender. Nem sabia da existência do overflow, mas depois de dar uma pesquisada entendi o que significa. Como já dizia um grande sábio "Ah Agora eu entendi, agora eu saquei, agora tudo faz sentido, agora todas as peças se encaixaram". De verdade, muito obrigado pela ajuda! 1 1 Citar Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Agosto 10, 2022 em 19:41 Compartilhar Postado Agosto 10, 2022 em 19:41 Não faz parte de sua dúvida, mas eis um código que não é recursivo e usa aritmética de múltipla precisão e te permite calcular o fatorial de qualquer valor inteiro, positivo, dentro da faixa de um unsigned long int. // Calcula fatorial usando aritmética de multipla precisão. // // Compilar com: // cc -O2 -o factmp factmp.c -lgmp // // Não esquecer de instalar libgmp-dev. // #include <stdio.h> #include <stdlib.h> #include <gmp.h> #include <errno.h> #include <time.h> int main(int argc, char *argv[]) { char *p; mpz_t r; unsigned long n, c, total; time_t t1, t2; if ( argc != 2 ) { fprintf( stderr, "Usage: %s <value>\n", argv[0] ); return EXIT_FAILURE; } // O valor deve ser inteiro e dentro da faixa de unsigned long int. errno = 0; n = strtoul( *++argv, &p, 10 ); if ( errno == ERANGE || *p ) { fputs( "ERROR: Invalid value.\n", stderr ); return EXIT_FAILURE; } // Inicializa r e seta-o com 1. mpz_init_set_ui(r, 1); t1 = time( NULL ); c = 0; total = n; while ( n >= 1 ) { mpz_mul_ui( r, r, n-- ); printf( "%.2f%% complete... \r", 100.0 * ++c / total ); } putchar( '\n' ); t2 = time( NULL ); mpz_out_str( stdout, 10, r ); putchar('\n'); // Joga r no lixo. mpz_clear(r); printf( "Total time: %lu seconds.\n", t2 - t1 ); return EXIT_SUCCESS; } Mas, atenção: Se você usar valores muito grandes (maiores que 100000, por exemplo), o tempo de calculo será bem grande (tente!). []s Fred Citar Link para o comentário Compartilhar em outros sites More sharing options...
Posts Recomendados
Participe da conversa
Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.