Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

6600LIVE

Factorial e Soma com bugs?

Recommended Posts

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?

Share this post


Link to post
Share on other 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)

Share this post


Link to post
Share on other 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;
}

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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!  :)

Share this post


Link to post
Share on other sites
6600LIVE

Reparei agora que para n<=10 tambem nao funciona bem...

Será que o erro está na propria funçao factorial?!

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.