class CalculaPi {
/** n é o número de iterações */
double calcula1 (int n) {
double pi;
// Usando a fórmula do jeito que está, mas usando um truque
// ou seja, calculando os termos menores primeiro
double _16n; // 16 elevado a -n
_16n = 1.0;
for (int k = n; k > 0; --k) {
_16n /= 16.0;
}
// Agora usando a fórmula
pi = 0.0;
for (int k = n; k >= 0; --k) {
pi += _16n * (
4.0 / (8 * k + 1)
- 2.0 / (8 * k + 4)
- 1.0 / (8 * k + 5)
- 1.0 / (8 * k + 6));
_16n *= 16.0;
System.out.printf ("%g%n", pi);
}
return pi;
}
/** epsilon é a margem de erro */
double calcula2 (double epsilon) {
double pi;
double _16n; // 16 elevado a -n
// Agora vamos usar a fórmula calculando os termos maiores primeiro.
// Para evitar que entre em loop, iremos limitar o número de iterações para 100.
pi = 0.0;
_16n = 1.0;
for (int k = 0; k < 100; ++k) {
double newPi = pi + _16n * (
4.0 / (8 * k + 1)
- 2.0 / (8 * k + 4)
- 1.0 / (8 * k + 5)
- 1.0 / (8 * k + 6));
if (Math.abs (newPi - pi) < epsilon) {
return newPi;
}
pi = newPi;
_16n /= 16.0;
}
return pi;
}
public static void main(String[] args) {
CalculaPi p = new CalculaPi();
double pi = p.calcula2 (1E-10);
System.out.printf ("pi = %.12g%n", pi);
}
}
Na verdade descobri o seu erro. É que 1 / 16 == 0 (deveria ser: 1.0 / 16.0)
Dica: em Java, evite usar ao máximo o operador de exponenciação se for usar com expoente inteiro.
Se você viu o que fiz, não usei a exponenciação nenhuma vez.
[quote=thingol]Na verdade descobri o seu erro. É que 1 / 16 == 0 (deveria ser: 1.0 / 16.0)
Dica: em Java, evite usar ao máximo o operador de exponenciação se for usar com expoente inteiro.
Se você viu o que fiz, não usei a exponenciação nenhuma vez. [/quote]
Valeu, era isso mesmo, não acredito como não vi isso… e valeu pela dica.