Criei uma aplicação que calcula o fatorial de um inteiro x a partir do método:
[code]public class Fatorial
{
public int fatorial(int x)
{
if (x == 0)
return 1;
else
return x * fatorial(x - 1);
}
}
[/code]
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:
[code]import java.util.Scanner;
/**
*
@author Tales R. T. Carneiro
*/
public class FatorialTeste
{
/**
@param args the command line arguments
*/
public static void main(String[] args)
{
// TODO code application logic here
/**
Local variables
*/
int x;
int result;
int n;
int count;
double e;
/**
Asks for an integer
and reads it
*/
Scanner input = new Scanner(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
*/
Fatorial f = new Fatorial();
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);
}
}
[/code]
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:
[code]public class Fatorial
{
public int fatorial(int x)
{
if (x == 0)
return 1;
else
return x * fatorial(x - 1);
}
}
[/code]
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:
[code]import java.util.Scanner;
/**
*
@author Tales R. T. Carneiro
*/
public class FatorialTeste
{
/**
@param args the command line arguments
*/
public static void main(String[] args)
{
// TODO code application logic here
/**
Local variables
*/
int x;
int result;
int n;
int count;
double e;
/**
Asks for an integer
and reads it
*/
Scanner input = new Scanner(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
*/
Fatorial f = new Fatorial();
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);
}
}
[/code]
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?[/quote]
talesc, eu acho que este tópico aqui te ajuda, valeu!
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.
class CalculoE {
public double calcularE () {
double soma = 0.0;
double fator = 1.0;
for (int n = 1; n <= 24; ++n) {
soma += fator;
fator /= n;
}
return soma;
}
public double calcularE_metodo2() {
double[] fatores = new double [25];
double soma = 0.0;
double fator = 1.0;
for (int n = 1; n <= 24; ++n) {
fatores[n] = 1.0 / fator;
fator *= n;
}
for (int n = 24; n >= 1; n--) {
soma += fatores [n];
}
return soma;
}
public static void main (String[] args) {
CalculoE c = new CalculoE();
// 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());
}
}
[quote=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.
[code]
class CalculoE {
public double calcularE () {
double soma = 0.0;
double fator = 1.0;
for (int n = 1; n <= 24; ++n) {
soma += fator;
fator /= n;
}
return soma;
}
public double calcularE_metodo2() {
double[] fatores = new double [25];
double soma = 0.0;
double fator = 1.0;
for (int n = 1; n <= 24; ++n) {
fatores[n] = 1.0 / fator;
fator *= n;
}
for (int n = 24; n >= 1; n--) {
soma += fatores [n];
}
return soma;
}
public static void main (String[] args) {
CalculoE c = new CalculoE();
// 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());
}
}
[/code][/quote]
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?
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.
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.
[quote=Luiz Augusto Prado][quote=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.
[code]
class CalculoE {
public double calcularE () {
double soma = 0.0;
double fator = 1.0;
for (int n = 1; n <= 24; ++n) {
soma += fator;
fator /= n;
}
return soma;
}
public double calcularE_metodo2() {
double[] fatores = new double [25];
double soma = 0.0;
double fator = 1.0;
for (int n = 1; n <= 24; ++n) {
fatores[n] = 1.0 / fator;
fator *= n;
}
for (int n = 24; n >= 1; n--) {
soma += fatores [n];
}
return soma;
}
public static void main (String[] args) {
CalculoE c = new CalculoE();
// 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());
}
}
[/code][/quote]
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?
[/quote]
Show mesmo entanglement! Como o regis_hideki já disse, com essas informações já dá para resolver tranquilo!
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.
[quote=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.[/quote]
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.