Ir ao conteúdo
  • Cadastre-se

C Funcao que retorna Vetor de Fatorial


UmPrograma

Posts recomendados

Bom dia. Como vão?

 

Estava a resolver um exercício que pedia que criasse dois vetor, e um deles deve conter o fatorial do outro.

Ja resolvi problemas de fatorial. Ja ordenei um vetor (dentro de uma funcao por meio de ponteiro). Ai achei que juntando algumas coisas que fiz nesses exercicios conseguiria resolver esse outro.

 

Acho que deva ser algum detalhe que esta passando despercebido. Se puderem da uma olhada no codigo, agradecido.

 

/**6. Faça um procedimento que recebe 2 vetores A e B de tamanho 10 de inteiros, por parâmetro. Ao final
 do procedimento B deve conter o fatorial de cada elemento de A. O vetor B deve retornar alterado. */
#include <stdio.h>
main(){
    int i, vet[5], vet2[5];

    printf("Entre com os valores do vetor.\n");
    for(i=0;i<5;i++){
        printf("Vetor [%d]: ", i);
        scanf("%d", &vet[i]);
    }
    printf("\n\nInformamos que o valor do vetor 1 foi copiado para o vetor 2.\n");
    for(i=0;i<5;i++){
        vet2[i]=vet[i];
    }
    int mudar(int *vet2);
    printf("\nO vetor de fatorial e o seguinte.\n");
    for(i=0;i<5;i++){
        printf("Vetor [%d] : %d.\n", i, vet2[i]);
    }
return 0;
}
int mudar(int *vet2){
    int i, j=1, num;
    for(i=0;i<5;i++){
        num=vet2[i];
        j=1;
        for(num=num;num>=1;num=num-1){
            j=j*num;
        }
        vet2[i]=j;
    }
}

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Josesousa como também tô aqui p aprender resolvi fazer esse exercício de um modo diferente:

 

/**6. Faça um procedimento que recebe 2 vetores A e B de tamanho 10 de inteiros, por parâmetro. Ao final
 do procedimento B deve conter o fatorial de cada elemento de A. O vetor B deve retornar alterado. */

#include <stdio.h>

void calc_fatorial(long *v1, long *v2);
long fat(long n);

int main(){

    short i;
    long vet[5], vet2[5];

    // inicializa os vetores
    for (i = 0; i < 5; i++) {
        vet[i] = 0;
        vet2[i] = 0;
    }

    printf("Entre com os valores do vetor.\n");
    for (i = 0; i < 5; i++) {
        printf("Vetor [%d]: ", i);
        scanf("%ld", &vet[i]);
    }

    calc_fatorial(vet, vet2);

    printf("\nO vetor de fatorial e o seguinte.\n");

    for (i = 0; i < 5; i++) {
        printf("Vetor [%d] : %ld\n", i, vet2[i]);
    }

    return 0;
}


long fat(long n) {
    return n < 2 ? 1 : n * fat(n - 1);
}


void calc_fatorial(long *v1, long *v2) {

    short i;

    for (i = 0; i < 5; i++) {
        v2[i] = fat(v1[i]);
    }
}

 

Link para o comentário
Compartilhar em outros sites

@AnsiC Seria algo como fatorial d um número negativo?

Até onde sei só é possível calcular o fatorial de números >= 0. Logo, no exercício, teria q validar se o número digitado é positivo ou não

Entendi  q seria isso. Poderia ser mais específico? 

Link para o comentário
Compartilhar em outros sites

2 minutos atrás, giu_d disse:

@AnsiC Seria algo como fatorial d um número negativo?

Até onde sei só é possível calcular o fatorial de números >= 0. Logo, no exercício, teria q validar se o número digitado é positivo ou não

Entendi  q seria isso. Poderia ser mais específico? 

Até onde nós sabemos não existe fatorial de número negativo. Entretanto sua implementação, que mista de recursividade e laço, está respondendo que é 1 é fatorial para qualquer número menor que 2.

 

2 horas atrás, giu_d disse:

return n < 2 ? 1 : n * fat(n - 1);

Veja o que diz: Se n é menor que 2 então a resposta é 1. Existem infinitos números menores que 2 cujo sua proposição admitem como sendo fatorial 1. Detalhe o enunciado do problema não garante que os valores são inteiros positivos.

 

 

Observe:

2 horas atrás, giu_d disse:

/**6. Faça um procedimento que recebe 2 vetores A e B de tamanho 10 de inteiros, por parâmetro. Ao final do procedimento B deve conter o fatorial de cada elemento de A. O vetor B deve retornar alterado. */

Claro que uma perspectiva menos rigorosa isso seria irrelevante. Mais hoje estou perfeccionista de mais!

 

 

Dúvidas, críticas ou sugestões? 

adicionado 4 minutos depois

"perfeccionista" com relação ao trabalho dos outros !

Link para o comentário
Compartilhar em outros sites

21 minutos atrás, AnsiC disse:

Veja o que diz: Se n é menor que 2 então a resposta é 1

Verdade. Nesse cálculo estou apenas considerando os números 0 e 1. Fatorial de 0 e/ou 1 -> 1

Números 0 e 1 assumindo não haver números negativos no vetor

 

21 minutos atrás, AnsiC disse:

Detalhe o enunciado do problema não garante que os valores são inteiros positivos.

É essa a parte q precisa ser tratada

Link para o comentário
Compartilhar em outros sites

É uma pergunte meio estranha, mas onde é que esta sendo feito o calculo de fatoral?

Seria nessa parte?? -> 

11 horas atrás, giu_d disse:

long fat(long n) { return n < 2 ? 1 : n * fat(n - 1); }

 

É uma função diferente! (Nunca usei long ou short para declarar algum tipo, pensava que o usava da seguinte forma -> short int, long int)

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

9 horas atrás, giu_d disse:

 

9 horas atrás, AnsiC disse:

Detalhe o enunciado do problema não garante que os valores são inteiros positivos.

É essa a parte q precisa ser tratada

Precisamente, é apenas por rigorosidade ou perfeccionismo, pois a solução já está boa. Então com tratamento fica assim:

/** função fatorial -- retorna fatorial de inteiro se positivo */
long fatorial (long n){
        return n < 0? 0 : n == 0? 1 : n*fatorial (n - 1);
}
  1. Se n < 0? é verdadeiro então o valor da expressão é 0,
  2. Se não, então questiona Se n == 0? é verdadeiro então o valor da expressão é 1,
  3. Se não, então multiplica o valor de n atual pelo próximo n da sequencia chamando a função outra vez até que n == 0;

 

22 minutos atrás, Josesousa disse:

É uma função diferente! (Nunca usei long ou short para declarar algum tipo, pensava que o usava da seguinte forma -> short int, long int)

 Respondo: Quando omitimos o tipo o compilador assume o tipo padrão para essas situações que é int. Ao omitir o int demostra-se ter intimidade com a linguagem.

adicionado 0 minutos depois

Dúvidas, críticas ou sugestões?

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@AnsiC É, vendo a sua explicação com respeito a tratar com o fatorial de um número negativo, foi exatamente a resposta q encontrei depois de pesquisar a respeito disso. Em um tópico foi simulado o uso da função gama para calcular o fatorial d um número negativo, e a conclusão q se chegou é q o fatorial, nesse caso,  seria sempre 0

Inda estava em dúvida mas agora ficou bem claro. Obrigado! Já ajustei o código aqui :thumbsup:

@Josesousa A explicação da função q calcula o fatorial d um número foi dada acima pelo @AnsiC

Mas, para ficar mais fácil de entender, daria para reescrever a mesma função usando if-else ao invés de um operador ternário.

Poderia ficar assim a função:

long fatorial(long n) {

    if (n < 0) {
        return 0;
    } else if (n == 0) {
        return 1;
    } else {
        return n * fatorial(n - 1);
    }
}

teria outras formas para reescrever esse mesmo código usando o if-else, mas prefiro essa.

e, para fazer uso dessa função, um exemplo simples:

long x = fatorial(5);
printf("Fatorial: %ld\n", x);

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Vou tentar complementar (entrando também nessa questão dos detalhes)...

 

Um ponto importante estaria aqui:

11 horas atrás, AnsiC disse:

Detalhe o enunciado do problema não garante que os valores são inteiros positivos.

obs. 1: sendo que 0 e 1 são menores que 2 e também são válidos, uma frase mais precisa seria algo como: "não garante que os valores são não negativos", já 0 não é positivo.

 

 

De fato o enunciado só indica que devem ser inteiros:

21 horas atrás, Josesousa disse:

/**6. Faça um procedimento que recebe 2 vetores A e B de tamanho 10 de inteiros, por parâmetro. Ao final do procedimento B deve conter o fatorial de cada elemento de A. O vetor B deve retornar alterado. */

 

Ou seja, sugere que de fato podem ser negativos... aí a questão do resultado entra no inicialmente sugerido por@AnsiC:

12 horas atrás, AnsiC disse:

@giu_d Adapte sua solução para números negativos e positivos.

obs.2: mais um detalhe: "para negativos, nulos e positivos". (já que o zero também entra na conta!)

 

Desta forma, o vetor A[] pode sim ter inteiros negativos.. não tem problemas, apenas que os fatoriais só serão calculados para os "não negativos" (zero e positivos), ou seja, o vetor B[] só terá o fatorial ditos válidos e precisará de alguma coisa para indicar os "inexistentes".

 

Resumindo:

O fatorial de um número negativo NÃO É 0... na verdade, o fatorial de números negativos NÃO EXISTEM. É diferente. Pois, para "n!, n pertence aos naturais*", não aos inteiros, logo, números negativos estão fora de escopo...  (Fatorial de número negativo é análogo raiz quadrada de números negativos no mundo dos reais, ou seja, não existe!)

 

Daí, uma forma seria na hora de exibir os fatoriais, verificar o valor em B[]: como está utilizando "0" para os inválidos, se o número for maior igual a 1, exibe o número (será o fatorial do correspondente em A[]), caso contrário, exibe algo como: "Fatorial inexistente" ou "--" etc (indicando que não existe fatorial para o correspondente).

 

Uma outra forma poderia usar:

1 hora atrás, giu_d disse:

    if (n < 0) {
        return n;
    } 

 

Daí, em B[] conteria o próprio número... que no contexto, por ser negativo, referiria que é "inexistente", mas com a diferença que terá o mais uma "informação" que é o próprio número que original... 

 

 

O que acham?

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

18 minutos atrás, Simon Viegas disse:

Resumindo:

O fatorial de um número negativo NÃO É 0... na verdade, o fatorial de números negativos NÃO EXISTEM. É diferente. Pois, para "n!, n pertence aos naturais*", não aos inteiros, logo, números negativos estão fora de escopo...  (Fatorial de número negativo é análogo raiz quadrada de números negativos no mundo dos reais, ou seja, não existe!)

@Simon Viegas Boa essa explicação! quase revirei a internet ontem pesquisando por isso hehe

Link para o comentário
Compartilhar em outros sites

7 minutos atrás, Simon Viegas disse:

obs. 1: sendo que 0 e 1 são menores que 2 e também são válidos, uma frase mais precisa seria algo como: "não garante que os valores são não negativos", já 0 não é positivo

Exatamente, 0 também não e garantido. Por ser os implicantes os números negativos @Simon Viegas que faz jus um tratamento específico para o problema, ou seja, mesmo que 0 e um sejam menores que 2 e validem a proposição nos casos em que n > 0, o conjunto dos números negativos puseram em risco a solução do problema, e não o 0 e 1 que como já supracitado válidos. O detalhe que complementa a solução é

12 horas atrás, AnsiC disse:

enunciado do problema não garante que os valores são inteiros positivos.

Poderia ter dito: pelo enunciado do problema se admite também número negativos.

Ainda sim sua observação faz muito sentido.

 

 

25 minutos atrás, Simon Viegas disse:

obs.2: mais um detalhe: "para negativos, nulos e positivos". (já que o zero também entra na conta!)

Mais um observação muito mais de compreensão do que interpretação, provavelmente resultado do raciocínio da obs 1. Que claramente não remove o mérito de considerar 0 e 1 logicamente e matematicamente válidos. Quando na verdade apenas os valores menores que 0, ou seja números negativos são o problema da lógica

Reitero meus votos anteriores. 

 

29 minutos atrás, Simon Viegas disse:

O fatorial de um número negativo NÃO É 0... na verdade, o fatorial de números negativos NÃO EXISTEM. É diferente. Pois, para "n!, n pertence aos naturais*", não aos inteiros, logo, números negativos estão fora de escopo...  (Fatorial de número negativo é análogo raiz quadrada de números negativos no mundo dos reais, ou seja, não existe!)

Mais um vez, sua compreensão está a 1000/h. Em algum momento dizemos que 0 é o resultado? Só para ver melhor

 

13 horas atrás, AnsiC disse:

Até onde nós sabemos não existe fatorial de número negativo

 

13 horas atrás, AnsiC disse:

Até onde sei só é possível calcular o fatorial de números >= 0

 

 

Estamos os dois conscientes de que não existe fatorial de número negativo (eu até mais do que gostaria). Quanto a raiz de número negativo os sistemas de saída emitem NaN (Not a Number), isso é padronizado, pois há um conjunto de bits que representa tal resposta em todos os sistemas que conheço. Daí porque 0 não poderia ser tal padrão para essa situação em particular. Se tivesse me perguntado isso! Essa seria a resposta para sua obervação nesta citação:

 

46 minutos atrás, Simon Viegas disse:

caso contrário, exibe algo como: "Fatorial inexistente" ou "--" etc (indicando que não existe fatorial para o correspondente)

Exatamente quando houvesse a necessidade de imprimir a lista de fatores (e não há) aquele de fatorial NULO (0) terá sua saída não 0 e sim NaF análogo ao padrão NaN. NaF seria mesmo que Not a Factorial. É justificável ser 0 por 3 motivos?

1 porque não há como gravar um sentença deste tamanho em uma variável inteiro.

2 porque  0 é melhor representação de vazio nessa e em muitas outras situações, e por último 0 não pertence a sequencia dos fatorais  que vai de 1 ... ao infinito e além.

 

Dúvidas, críticas ou sugestões?

adicionado 3 minutos depois
1 hora atrás, Simon Viegas disse:

O que acham?

Eu gostei!

  • Amei 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Sobre:

42 minutos atrás, giu_d disse:

@Simon Viegas Boa essa explicação! quase revirei a internet ontem pesquisando por isso hehe

O que estou comentando é também uma mistura do que lembrava do tema, com revisada básica na internet... 

 

 

 

Sobre:

13 minutos atrás, AnsiC disse:

1 porque não há como gravar um sentença deste tamanho em uma variável inteiro.

Pois é! Atentado-se ao enunciado, de fato não é solicitado para "exibir B[]", rs. Só para ficar claro.. esse "Fatorial inexistente" estava me referindo a uma tradução do "0" na hora de exibir..., não para armazenar...  

 

Por sinal, esse conceito de NaN é bem interessante, coisa boa!! Não conhecia!! Vou dar uma pesquisada...

 

No caso, da mesma forma que se fosse "armazenado NaF" para os resultados dos negativos, na hora de exibir (se fosse necessário), poderia, analogamente, traduzir para algo mais próximo personalizado... (em vez de aparecer um código ou mesmo as letras NaF etc)

 

Resumidamente supus que seria implícito exibir os resultados, até mesmo para validar os resultados... ou seja, seria mais uma questão: exibir ou não exibir o vetor B?

 

No caso foge do enunciado ou está implícito?

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

41 minutos atrás, Simon Viegas disse:

Resumidamente supus que seria implícito exibir os resultados, até mesmo para validar os resultados... ou seja, seria mais uma questão: exibir ou não exibir o vetor B?

 

No caso foge do enunciado ou está implícito?

Consideremos por um breve instante isso, dentre tudo abordado enuncia-se também: "exiba as lista A e B"! Em 1 ou duas sentenças fazendo ou não alusão a mais que uma questão: Quaisquer que sejam as formas de exibir A e B, elas não devem ser iguais. Por quê? Porque o conjunto não é igual (em sua natureza), são diferentes pelas razões já elucidadas, essa diferença deve persiste desde o instante em que B fora preenchido até sua exibição na tela. Isso independe de ser 1 ou duas questões. 0 como fator diferencial não foi uma escolha arbitraria, contudo, pode ser qualquer outro valor que não inviabilize o conjunto lógico {f : F(x)} / f > -1.

 

52 minutos atrás, Simon Viegas disse:

No caso, da mesma forma que se fosse "armazenado NaF" para os resultados dos negativos, na hora de exibir (se fosse necessário), poderia, analogamente, traduzir para algo mais próximo personalizado... (em vez de aparecer um código ou mesmo as letras NaF etc)

  

Eu favoritei o sigla NaF (do termos inglês Not a Factorial) pelas aproximações tecnologias e cientificas. Mas isso não exclui qualquer fantasia injustificada ou justificada por quaisquer motivo que sejam. Não esse é o mérito da questão, porque não vejo escopo para tal discussão, ou seja use da representação que lhe agradar, pois o que realmente tem de significado é o diferencial que nos permite identificação do número negativo bem como sua nulidade para fatoriais. Ainda sim é uma outra questão, putativa ou complementante à lógica supor sua exibição não numérica, e continuo com NaF.

 

 

Dúvidas, críticas ou sugestões?

adicionado 51 minutos depois
2 horas atrás, Simon Viegas disse:

Por sinal, esse conceito de NaN é bem interessante, coisa boa!! Não conhecia!! Vou dar uma pesquisada...

Interessante, suponho duas coisa: 1 você nunca calculo a raiz de um número negativo usando sistemas computacionais modernos, 2 ou não lembra ao certo o que acontece quando calculamos a raiz de um número negativo usando uma calculadora simples ou linguagem de programação C.

 

Conheço 4 possível valores: 1.#IND, 1.#INF, NaN, e INF

o que acontece se calcular a raiz de número negativo em teu computador?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

 

1 hora atrás, AnsiC disse:

o que acontece se calcular a raiz de número negativo em teu computador?

 

No Windows 10 exibiu "Entrada inválida".

raiz_número_negativo.png

 

 

adicionado 12 minutos depois
4 horas atrás, Simon Viegas disse:

Daí, uma forma seria na hora de exibir os fatoriais, verificar o valor em B[]: como está utilizando "0" para os inválidos, se o número for maior igual a 1, exibe o número (será o fatorial do correspondente em A[]), caso contrário, exibe algo como: "Fatorial inexistente" ou "--" etc (indicando que não existe fatorial para o correspondente).

 

Coincidentemente (ou inconscientemente relacionado) deu o que tentei sugerir/complementar... o Windows 10 exibiu uma "tradução do erro" para uma linguagem mais amigável (em português e, no caso, sugerindo sobre o "motivo/causa", não o resultado)

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Poderia setar errno para indicar o erro:

http://man7.org/linux/man-pages/man3/errno.3.html

 

#include <errno.h>

/** funcao fatorial -- retorna fatorial de inteiro se maior ou igual a 0 */
long long int fatorial(long long int n) {
    if (n < 0){
        errno = EDOM;
        return = 0;
    }
    else {
        return n == 0 ? 1 : fatorial(n - 1) * n;
    }
}

 

 

Ou até mesmo já exibir a mensagem de erro e interromper o programa:

#include <stdio.h>
#include <errno.h>

/** funcao fatorial -- retorna fatorial de inteiro se maior ou igual a 0 */
long long int fatorial(long long int n) {
    if (n < 0){
        errno = EDOM;
        perror("Not A Factorial");
        exit(1);
    }
    else {
        return n == 0 ? 1 : fatorial(n - 1) * n;
    }
}

 

 

Outra opção seria especificar que a função recebe apenas inteiros maior ou igual a 0 como parâmetro:

/** funcao fatorial -- retorna fatorial de inteiro maior ou igual a 0 */
unsigned long long int fatorial(unsigned long long int n) {
    return n == 0 ? 1 : fatorial(n - 1) * n;
}

 

 

Note que usei o tipo long long int, pois na maioria das implementações long int é ambíguo, pois ou int é igual a long int com 4 bytes (normalmente quando se compila em 32 bits), ou long int é igual a long long int com 8 bytes (normalmente quando em 64 bits).

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

24 minutos atrás, Simon Viegas disse:

Coincidentemente (ou inconscientemente relacionado) deu o que tentei sugerir/complementar... o Windows 10 exibiu uma "tradução do erro" para uma linguagem mais amigável (em português e, no caso, sugerindo sobre o "motivo/causa", não o resultado)

"Entrada em válida" faz parte do conjunto de traduções padronizados do NaN, para o português! O mais importante é que isso corrobora para existência de uma exibição Não é Numérica! Duas conclusões: 1 existe um valor de retorno traduzido uma ou mais vezes que foi padronizado. 2 mesmo que o usuário sabia que não existe a raiz real de uma valor positivo o sistema trada de traduzir o valor universal dessa nulidade de acordo com dialeto do usuário.

 

Para a conclusão 2 é irrelevante porque NaN é o padrão as possíveis traduções são um conceito de implementação subjacente que está intricado ao dialeto do usuário, isso cai nos valores da individualidade e não da universalidade, justifica portanto a existência de múltiplas traduções na implementação, porém NaN pode sofrer quaisquer mudanças.

adicionado 7 minutos depois
17 minutos atrás, isrnick disse:

Poderia setar errno para indicar o erro:

http://man7.org/linux/man-pages/man3/errno.3.html

Concordo, POSIX!

 

17 minutos atrás, isrnick disse:

 

Ou até mesmo já exibir a mensagem de erro e interromper o programa:

Discordo!

 

18 minutos atrás, isrnick disse:

Note que usei o tipo long long int, pois na maioria das implementações long int é ambíguo, pois ou int é igual a long int com 4 bytes (normalmente quando se compila em 32 bits), ou long int é igual a long long int com 8 bytes (normalmente quando em 64 bits).

Existe uma ou mais bibliotecas para tradar desse probleminha. 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

1 hora atrás, AnsiC disse:

Sim,  inttypes.h também ambas podem assegurar um implementação segura!

 

A biblioteca inttypes.h inclui stdint.h, e apenas adiciona macros para facilitar o uso desses tipos inteiros com comprimento fixo nas funções printf() e scanf(), além de adicionar algumas funções para intmax_t (conversão de e para string, valor absoluto, divisão inteira)...

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!