Criei uma aplicação que calcula o fatorial de um inteiro x a partir do método:
public class Fatorial
{
public int fatorial(int x)
{
if (x == 0)
return 1;
else
return x * fatorial(x - 1);
}
}
A aplicação também avalia o valor da expressão e = 1 + 1/1! + 1/2! + 1/3! ... (n termos), onde n é dado pelo usuário. Abaixo apresentamos o código:
importjava.util.Scanner;/** * * @author Tales R. T. Carneiro */publicclassFatorialTeste{/** * @param args the command line arguments */publicstaticvoidmain(String[]args){// TODO code application logic here/** * Local variables */intx;intresult;intn;intcount;doublee;/** * Asks for an integer * and reads it */Scannerinput=newScanner(System.in);System.out.print("Entre com um inteiro positivo: ");x=input.nextInt();/** * Calculates the fatorial of an integer * and prints the result on the screen */Fatorialf=newFatorial();result=f.fatorial(x);System.out.printf("O fatorial de %d é: %d",x,result);/** * Calculates the value of the expression: * e = 1 + 1 / 1! + 1 / 2! + 1 / 3! ... (n terms) */System.out.print("Entre com um inteiro n > 0: ");n=input.nextInt();if(n==1)e=1;else{count=1;e=1;while(count<n){e=e+1/(double)f.fatorial(count);count++;}}System.out.printf("e = %.8f",e);}}
Acontece que quando calculo um fatorial de um inteiro muito grande o valor avaliado pelo java é zero. Ao mesmo tempo quando n muito grande temos e = infinito quando na verdade a série deveria convergir. Ou seja, quando utilizamos números muito elevados o programa produz resultados errados. Por que isso acontece?
Criei uma aplicação que calcula o fatorial de um inteiro x a partir do método:
public class Fatorial
{
public int fatorial(int x)
{
if (x == 0)
return 1;
else
return x * fatorial(x - 1);
}
}
A aplicação também avalia o valor da expressão e = 1 + 1/1! + 1/2! + 1/3! ... (n termos), onde n é dado pelo usuário. Abaixo apresentamos o código:
importjava.util.Scanner;/** * * @author Tales R. T. Carneiro */publicclassFatorialTeste{/** * @param args the command line arguments */publicstaticvoidmain(String[]args){// TODO code application logic here/** * Local variables */intx;intresult;intn;intcount;doublee;/** * Asks for an integer * and reads it */Scannerinput=newScanner(System.in);System.out.print("Entre com um inteiro positivo: ");x=input.nextInt();/** * Calculates the fatorial of an integer * and prints the result on the screen */Fatorialf=newFatorial();result=f.fatorial(x);System.out.printf("O fatorial de %d é: %d",x,result);/** * Calculates the value of the expression: * e = 1 + 1 / 1! + 1 / 2! + 1 / 3! ... (n terms) */System.out.print("Entre com um inteiro n > 0: ");n=input.nextInt();if(n==1)e=1;else{count=1;e=1;while(count<n){e=e+1/(double)f.fatorial(count);count++;}}System.out.printf("e = %.8f",e);}}
Acontece que quando calculo um fatorial de um inteiro muito grande o valor avaliado pelo java é zero. Ao mesmo tempo quando n muito grande temos e = infinito quando na verdade a série deveria convergir. Ou seja, quando utilizamos números muito elevados o programa produz resultados errados. Por que isso acontece?
talesc, eu acho que este tópico aqui te ajuda, valeu!
Ajudou sim! Mas eu queria manter uma classe Fatorial em separado, em outra classe fora daquela com o método main.
Luiz_Augusto_Prado
não entendi. pq acha que não dá pra fazer isso que quer se utilizar big integer?
E
entanglement
Aqui dou duas formas de calcular o número e.
Uma delas é somar os elementos do maior para o menor (ou seja, 1/0! + 1/1! + 1/2! …)
A outra, que é a mais exata, é somar os elementos do menor para o maior (ou seja, 1/24! + 1/23! + 1/22! … + 1/2! + 1/1! + 1/0!)
Tanto na primeira quanto na segunda eu uso a fórmula padrão, mas o cálculo do fatorial é implícito, não explícito. Isso economiza um bocadinho de tempo, já que não preciso ficar recalculando o fatorial para cada termo da expressão que calcula e.
classCalculoE{publicdoublecalcularE(){doublesoma=0.0;doublefator=1.0;for(intn=1;n<=24;++n){soma+=fator;fator/=n;}returnsoma;}publicdoublecalcularE_metodo2(){double[]fatores=newdouble[25];doublesoma=0.0;doublefator=1.0;for(intn=1;n<=24;++n){fatores[n]=1.0/fator;fator*=n;}for(intn=24;n>=1;n--){soma+=fatores[n];}returnsoma;}publicstaticvoidmain(String[]args){CalculoEc=newCalculoE();// Valor esperado: 2,7182818284590452353602874713527...// Valor impresso: 2.7182818284590455 - note que o último dígito é 5, não 2 (diferença: +3)System.out.println(c.calcularE());// Valor impresso: 2.7182818284590450 - note que o último dígito é 0, não 2 (diferença: -2) System.out.println(c.calcularE_metodo2());}}
Luiz_Augusto_Prado
entanglement:
Aqui dou duas formas de calcular o número e.
Uma delas é somar os elementos do maior para o menor (ou seja, 1/0! + 1/1! + 1/2! ....)
A outra, que é a mais exata, é somar os elementos do menor para o maior (ou seja, 1/24! + 1/23! + 1/22! ... + 1/2! + 1/1! + 1/0!)
Tanto na primeira quanto na segunda eu uso a fórmula padrão, mas o cálculo do fatorial é implícito, não explícito. Isso economiza um bocadinho de tempo, já que não preciso ficar recalculando o fatorial para cada termo da expressão que calcula e.
classCalculoE{publicdoublecalcularE(){doublesoma=0.0;doublefator=1.0;for(intn=1;n<=24;++n){soma+=fator;fator/=n;}returnsoma;}publicdoublecalcularE_metodo2(){double[]fatores=newdouble[25];doublesoma=0.0;doublefator=1.0;for(intn=1;n<=24;++n){fatores[n]=1.0/fator;fator*=n;}for(intn=24;n>=1;n--){soma+=fatores[n];}returnsoma;}publicstaticvoidmain(String[]args){CalculoEc=newCalculoE();// Valor esperado: 2,7182818284590452353602874713527...// Valor impresso: 2.7182818284590455 - note que o último dígito é 5, não 2 (diferença: +3)System.out.println(c.calcularE());// Valor impresso: 2.7182818284590450 - note que o último dígito é 0, não 2 (diferença: -2) System.out.println(c.calcularE_metodo2());}}
muito legal!
O estudo das séries de Taylor e MacLaurin são fundamentais para desenvolvimento de programas que trabalham com calculo pesado.
vc viu se essa é a formula conhecida que converge mais rápido?
regis_hideki
Com as informações que deram, já dá pra resolver o problema, mas acho que ainda não dá pra entender muito bem porque esse erro ocorre. Se quiser entender porque números muito grandes podem resultar em valores negativos e números muito pequenos podem resultar em zero, recomendo dar uma pesquisada sobre overflow e underflow.
E
entanglement
Do jeito que ele calculou o fatorial (acumulando os resultados em um int, e retornando um int) vai dar problemas mesmo.
É que quando o resultado de uma multiplicação de dois ints excede o valor de um int, o resultado é indefinido (pode ser negativo, positivo, zero etc.).
Se a pessoa que fez esse cálculo que “diverge” visse que o valor do fatorial, para n > 12, dá resultados errados do jeito que ele escreveu, veria que na verdade o cálculo é que está sendo feito indevidamente.
A série de Taylor para o cálculo de “e” é muito estável e não “diverge” de forma alguma.
B
brunoeac
Luiz Augusto Prado:
entanglement:
Aqui dou duas formas de calcular o número e.
Uma delas é somar os elementos do maior para o menor (ou seja, 1/0! + 1/1! + 1/2! ....)
A outra, que é a mais exata, é somar os elementos do menor para o maior (ou seja, 1/24! + 1/23! + 1/22! ... + 1/2! + 1/1! + 1/0!)
Tanto na primeira quanto na segunda eu uso a fórmula padrão, mas o cálculo do fatorial é implícito, não explícito. Isso economiza um bocadinho de tempo, já que não preciso ficar recalculando o fatorial para cada termo da expressão que calcula e.
classCalculoE{publicdoublecalcularE(){doublesoma=0.0;doublefator=1.0;for(intn=1;n<=24;++n){soma+=fator;fator/=n;}returnsoma;}publicdoublecalcularE_metodo2(){double[]fatores=newdouble[25];doublesoma=0.0;doublefator=1.0;for(intn=1;n<=24;++n){fatores[n]=1.0/fator;fator*=n;}for(intn=24;n>=1;n--){soma+=fatores[n];}returnsoma;}publicstaticvoidmain(String[]args){CalculoEc=newCalculoE();// Valor esperado: 2,7182818284590452353602874713527...// Valor impresso: 2.7182818284590455 - note que o último dígito é 5, não 2 (diferença: +3)System.out.println(c.calcularE());// Valor impresso: 2.7182818284590450 - note que o último dígito é 0, não 2 (diferença: -2) System.out.println(c.calcularE_metodo2());}}
muito legal!
O estudo das séries de Taylor e MacLaurin são fundamentais para desenvolvimento de programas que trabalham com calculo pesado.
vc viu se essa é a formula conhecida que converge mais rápido?
Show mesmo entanglement! Como o regis_hideki já disse, com essas informações já dá para resolver tranquilo!
R
raghy
vi o tópico sobre matemática e resolvi falar de meu problema sobre fatoração e equação de 1 e 2 grau, está no meu site, com link para download em 4shared.com o site é www.raghy.net23.net está no link JAVA, o programa é o matemática java.
Aliás também coube aqui no anexo, envio para apreciação…
está em andamento (sempre está em andamento) , mas funciona tudo até então.
B
brunoeac
raghy:
vi o tópico sobre matemática e resolvi falar de meu problema sobre fatoração e equação de 1 e 2 grau, está no meu site, com link para download em 4shared.com o site é www.raghy.net23.net está no link JAVA, o programa é o matemática java.
Aliás também coube aqui no anexo, envio para apreciação…
está em andamento (sempre está em andamento) , mas funciona tudo até então.
Show também raghy, valeu!
JavaDreams
Experimenta dar uma olhada nos livros abaixo
mas somente nos capítulos que tratam do assunto:
Java Use a Cabeça
Jaca Como Programar
Não sou muito fã de matemática mas tive
uma boa base vendo os capítulos que falam
sobre tamanho de tipos e comparação entre tipos,
estouro/derramamento, dentre outra coisas.