Realmente é um metodo bastante demorado…
mas é o mais simples que consegui achar.
Ouvi falar do metodo de Pell… Alguem sabe como implementar ?
Realmente é um metodo bastante demorado…
mas é o mais simples que consegui achar.
Ouvi falar do metodo de Pell… Alguem sabe como implementar ?
[quote=entanglement][quote=carlucio]Galera consegui uma formula pra todos os casos
public double calculaRaiz(double valor) {
double fatorCalculo = 0.00001; //quanto menor o fator maior a precisao. Ex.: 0.0001
while (fatorCalculo * fatorCalculo < valor) {
fatorCalculo += 0.00001;
}
return fatorCalculo;
Só um problema, na raiz de 100 o resultado é
10.00000999979059
Alguem ajuda como tirar os 0 depois da virgula caso o numero seja exato?[/quote]
Cruz credo, isso é que se chama de método tosco para achar uma raiz quadrada. Se valor for 1000000000, quanto tempo vai ficar rodando esse algoritmo?[/quote]
É tosco, mas sabe que essa idéia não é de se jogar fora?
Pensei em uma melhoria, começar com um fator de calculo grande e ir diminuindo conforme necessario.
Se quiser uma idéia simples de entender, então use o método da bissecção. Ele é um método mais lento que o de Newton, mas é bem simples de explicar.
Basicamente, você pega um número, e vê se um determinado chute foi maior ou menor que o valor esperado. Se for maior, então você faz a média entre o valor anterior menor e esse valor, e tenta de novo. Se for menor, então você faz a média entre o valor anterior maior e esse valor, e tenta de novo.
Digamos que você tenha o número 123456. Esse número é maior que 1, então a sua raiz quadrada é menor que 123456, mas maior que zero.
Vamos chutar que a raiz quadrada seja a média entre 0 e 123456, ou seja, 61728.
Mas 61728 ao quadrado é 3810345984, que é maior que 123456.
Então vamos achar a média entre 0 e 61728 , que é 30864.
30864 ao quadrado é 952586496, maior que 123456.
A média entre 0 e 30864 é 15432.
15432 ao quadrado = 238146624, maior que 123456.
A média entre 0 e 15432 é 7716.
7716 ao quadrado = 59536656, maior que 123456.
A média entre 0 e 7716 é 3858.
3858 ao quadrado é 14884164
A média entre 0 e 3858 é 1929
1929 ao quadrado é 3721041
A média entre 0 e 1929 é 964,5
964,5 ao quadrado é 930260,25
A média entre 0 e 964,5 é 482,25
482,25 ao quadrado é 232565,0625 -> note que já está ficando perto de 123456 
A média entre 0 e 482,25 é 241,125
241,125 ao quadrado é 58141,265625 , QUE É MENOR QUE 123456.
Portanto, você deve calcular a média entre 241,125 e 482,25, que é 361,6875.
361,6875 ao quadrado é 130817,84765625, que é MAIOR que 123456.
Portanto você deve calcular a média entre 241,125 e 361,6875, que é 301,40625
e assim por diante.
O valor esperado é 351,36306009596398663933384640418 .
[quote=gomesrod][quote=entanglement][quote=carlucio]Galera consegui uma formula pra todos os casos
public double calculaRaiz(double valor) {
double fatorCalculo = 0.00001; //quanto menor o fator maior a precisao. Ex.: 0.0001
while (fatorCalculo * fatorCalculo < valor) {
fatorCalculo += 0.00001;
}
return fatorCalculo;
Só um problema, na raiz de 100 o resultado é
10.00000999979059
Alguem ajuda como tirar os 0 depois da virgula caso o numero seja exato?[/quote]
Cruz credo, isso é que se chama de método tosco para achar uma raiz quadrada. Se valor for 1000000000, quanto tempo vai ficar rodando esse algoritmo?[/quote]
É tosco, mas sabe que essa idéia não é de se jogar fora?
Pensei em uma melhoria, começar com um fator de calculo grande e ir diminuindo conforme necessario.[/quote]
Continuo achando tosco. Vou achar tosco até a morte.
[quote=entanglement]Se quiser uma idéia simples de entender, então use o método da bissecção. Ele é um método mais lento que o de Newton, mas é bem simples de explicar.
Basicamente, você pega um número, e vê se um determinado chute foi maior ou menor que o valor esperado. Se for maior, então você faz a média entre o valor anterior menor e esse valor, e tenta de novo. Se for menor, então você faz a média entre o valor anterior maior e esse valor, e tenta de novo.
Digamos que você tenha o número 123456. Esse número é maior que 1, então a sua raiz quadrada é menor que 123456, mas maior que zero.
Vamos chutar que a raiz quadrada seja a média entre 0 e 123456, ou seja, 61728.
Mas 61728 ao quadrado é 3810345984, que é maior que 123456.
Então vamos achar a média entre 0 e 61728 , que é 30864.
30864 ao quadrado é 952586496, maior que 123456.
A média entre 0 e 30864 é 15432.
15432 ao quadrado = 238146624, maior que 123456.
A média entre 0 e 15432 é 7716.
7716 ao quadrado = 59536656, maior que 123456.
A média entre 0 e 7716 é 3858.
3858 ao quadrado é 14884164
A média entre 0 e 3858 é 1929
1929 ao quadrado é 3721041
A média entre 0 e 1929 é 964,5
964,5 ao quadrado é 930260,25
A média entre 0 e 964,5 é 482,25
482,25 ao quadrado é 232565,0625 -> note que já está ficando perto de 123456 
A média entre 0 e 482,25 é 241,125
241,125 ao quadrado é 58141,265625 , QUE É MENOR QUE 123456.
Portanto, você deve calcular a média entre 241,125 e 482,25, que é 361,6875.
361,6875 ao quadrado é 130817,84765625, que é MAIOR que 123456.
Portanto você deve calcular a média entre 241,125 e 361,6875, que é 301,40625
e assim por diante.
O valor esperado é 351,36306009596398663933384640418 . [/quote]
hahaha praticamente uma busca binária.
Não é “praticamente uma busca binária”. O método de bissecção É UMA BUSCA BINÁRIA.
Vou pegar o programa que mostrei e adaptá-lo para busca binária. Obviamente não vou usar double, senão vou resolver o problema do distinto cidadão. Se ele quiser entender o algoritmo e traduzi-lo para double…
package guj;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class MetodoBisseccao {
public static BigDecimal sqrt (BigDecimal x, int n) {
BigDecimal eps = BigDecimal.ONE.scaleByPowerOfTen(-n);
BigDecimal x0 = BigDecimal.ZERO, x1 = x;
BigDecimal two = BigDecimal.valueOf(2L);
BigDecimal previousGuess, guess = x0;
do {
previousGuess = guess;
guess = x0.add(x1).divide(two, n, RoundingMode.HALF_EVEN);
int comparison = guess.pow(2).compareTo (x);
if (comparison > 0) {
x1 = guess;
} else if (comparison < 0) {
x0 = guess;
} else {
break;
}
} while (guess.subtract(previousGuess).abs().compareTo(eps) > 0);
return guess;
}
/**
* @param args
*/
public static void main(String[] args) {
// 1234567890123456789012345678901234567890123456789012345678
System.out.println (sqrt (new BigDecimal ("3.1415926535897932384626433832795028841971693993751058209749"), 58));
// Esperado: 1.7724538509055160272981674833411451827975494561223871282137
// Mostra: 1.7724538509055160272981674833411451827975494561223871282137
System.out.println (sqrt (BigDecimal.valueOf(123456L), 58));
// Mostra: 351.3630600959639866393338464041805575975151828716931452816598
}
}
[quote=gomesrod][quote=entanglement][quote=carlucio]Galera consegui uma formula pra todos os casos
public double calculaRaiz(double valor) {
double fatorCalculo = 0.00001; //quanto menor o fator maior a precisao. Ex.: 0.0001
while (fatorCalculo * fatorCalculo < valor) {
fatorCalculo += 0.00001;
}
return fatorCalculo;
Só um problema, na raiz de 100 o resultado é
10.00000999979059
Alguem ajuda como tirar os 0 depois da virgula caso o numero seja exato?[/quote]
Cruz credo, isso é que se chama de método tosco para achar uma raiz quadrada. Se valor for 1000000000, quanto tempo vai ficar rodando esse algoritmo?[/quote]
É tosco, mas sabe que essa idéia não é de se jogar fora?
Pensei em uma melhoria, começar com um fator de calculo grande e ir diminuindo conforme necessario.[/quote]
Eu nunca veio uma lógica como tosca, lógica é sempre lógica assim como ponto de vista…
Agora a desvantagem desta lógica é que para por exemplo se achar a raiz quadrada de 81, sendo sabido por todos q é 9… O programa
executaria literalmente cerca de 900 mil vezes… uau…!!!
Pelo metodo de Pell
[code]package JavaIniciante;
public class CalcMatematico {
public static int Raiz(int num) {
int guardaNum = num;
int raiz = 0;
for (int i = 1; true ; i += 2) {
num -= i;
if (num < i) {
if (num != 0) {
System.out.println("Nao possui raiz exata");
return raiz;
} else {
raiz++;
break;
}
}
raiz++;
}
return raiz;
}
}[/code]