Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

6600LIVE

Factorial e Soma com bugs?

Mensagens Recomendadas

6600LIVE

Boas

Encontrei este codigo para calcular recursivamente o factorial de um numero:

#include <stdio.h>

void main()
{
        int num, fact=1, i;

        printf("\n\nCalculo do Factorial\n\n");

        printf("Numero: ");
        scanf("%d", &num);

        for( i=1; i<=num; i++)
                fact = fact * i;

        printf("\n%d! = %d\n\n", num, fact);
}

So que a partir do 13 ou 14! o valor apresentado é incorrecto. PK?

E ja agora, para somar os valores todos de 1 até n:


soma=0;
        for(i=0;i<=n;i++)
            soma=(soma+i);

Apresenta, de facto a soma, mas depois aparece mais um valor à frente sem sentido.. Por exemplo, se for 20... Aparece 210-2102132736

O que tenho mal para isto acontece?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
6600LIVE

Referes-te ao do factorial certo?

Então sendo x=factorial(n) dentro do main, em vez de int x passa a long x?

Ja experimentei e nao consegui :S

E relativamente à soma, se for individual fica bem, caso contrario não...

(isto é para um main em que tem uma entrada "n" e depois obdece a 3 if cnsoante o n... um para somar, outro para factorial e outro para soma factorial)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
6600LIVE

Vou colocar aqui o programa mesmo:

#include <stdio.h>
#include <stdlib.h>

int factorial(int n)
{
    if(n==0 || n==1)
        return 1;
    else
        return (n*factorial(n-1));
}

int main()
{
    int i, j, soma, n;
    int x;
    printf("Qual o valor? ");
    scanf("%d", &n);
    if(n>=20)
    {
        soma=0;
        for(i=0;i<=n;i++)
            soma=soma+i;
        printf("%d", soma);
    }
    if(10<n<20)
    {
        x=factorial(n);
        printf("%d", x);
    }
    if(n<=10)
    {
        soma=0;
        for(j=1;j<=n;j++)
            soma=soma+factorial(j);
        printf("%d", soma);
    }
    return 0;
}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

É uma questão de precisão. Um int apenas pode guardar números até 2^31-1 (em 32 bits) ou 2^63-1 (em 64 bits).

Podes resolver o problema usando um long.

Onde está o long int, @6600LIVE?


here since 2009

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
6600LIVE

Nessa versao que aí coloquei nao está, porque experimentei colocá-lo no inicio em vez de ter int x, long x e mesmo assim não deu. Daí ter mantido a versao original para vos perguntar onde é que o deveria colocar, partindo do principio que onde eu pus estava mal!  :)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
6600LIVE

Experimentei esse factorial iterativo que me indicaste em vez do recursivo, utilizando este codigo:

#include <stdio.h>
#include <stdlib.h>

unsigned long iter_factorial(int n) {
    long accu = 1;
    int i;
    for(i = 1; i <= n; i++) {
        accu *= i;
    }
    return accu;
}

int main()
{
    int n=15;
    long x;
    x=iter_factorial(n);
    printf("%d", x);
    return 0;
}

Utilizei os long em vez de int e ainda assim o factorial de 15 está errado! Auch xD Não tou mesmo a ver...

Ja agora, no codigo completo que indiquei acima, a para valores menores que 10 o resultado deveia ser a soma dos factoriais. Por exemplo, n=3, o resultado devia ser 3x2x1+2x1+1=9 .. o resultado apresentado é  69, ou seja ele esta a imprimir o valor do factorial de 3 e so depois a soma.. :S

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
TheDark

É uma questão de precisão. Um int apenas pode guardar números até 2^31-1 (em 32 bits) ou 2^63-1 (em 64 bits).

Podes resolver o problema usando um long.

Na verdade, int e long têm ambos 32bit. long long é que tem 64 bit. Claro que isso depende da implementação do compilador, e possivelmente das opções do mesmo, e não tanto da arquitectura utilizada (o compilador é que decide o que manda para o CPU, e como o CPU interpreta o que lhe manda), mas regra geral (leia-se, nos compiladores mais utilizados) é assim. O que mudou de 32 para 64 bits foi o endereçamento de memória, não o tamanho do tipo int.

Qualquer dúvida, experimentem o seguinte código em x32 e x64:

int main() {
printf("sizeof(int) %d\n", sizeof(int));
printf("sizeof(long) %d\n", sizeof(long));
printf("sizeof(long long) %d\n", sizeof(long long));
printf("sizeof(int*) %d\n", sizeof(int*));
return 0;
}

Output (32-bit):

sizeof(int) 4

sizeof(long) 4

sizeof(long long) 8

sizeof(int*) 4

Output (64-bit):

sizeof(int) 4

sizeof(long) 4

sizeof(long long) 8

sizeof(int*) 8

Dito isto, usa long long em vez de long, e não mistures unsigned com signed.


Desaparecido.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.