Ajuda: Raiz Quadrada sem SQRT

32 respostas
C

Ola galera,

alguem conhece um metodo de raiz quadrada com iteração que nao seja o Math.sqrt

E o de raiz cubica tmbm .

Agradeço

32 Respostas

B

http://en.wikipedia.org/wiki/Methods_of_computing_square_roots (talvez esse artigo da Wikipedia esteja traduzido)
http://www.mathpath.org/Algor/cuberoot/cube.root.newton.htm

Eder_Peixoto

Mas o teu problema então não seria Java, mas sim matemática.

Eder_Peixoto

Mas o teu problema então não seria Java, mas sim matemática.

Rafael_Guerreiro

carlucio:
Ola galera,

alguem conhece um metodo de raiz quadrada com iteração que nao seja o Math.sqrt

E o de raiz cubica tmbm .
Agradeço


E se você multiplicar a variável por ela mesma 2 vezes? É isso que você está querendo?

Como eu faria:

import java.util.Scanner;
class Potencia
{
   public static void main (String args [])
   {
      Scanner sc = new Scanner (System.in);
      int base, elevado, resultado;
      
      System.out.println("Digite a base da potenciacao: ");
      base = sc.nextInt();
      
      System.out.println("Digite a potencia: ");
      elevado = sc.nextInt();
      
      resultado = base;
      for (int cont = 1; cont <= elevado; cont++)
      {
         resultado = resultado * base;
      }
      
      System.out.println("O resultado eh: " + resultado);
   } 
}

P.S.: Não testei e fiz com pressa.

adriano_si

1º - Pra que ??
2º - Por que ??
3º - Quanto vou ganhar ?? (heueheuehu esse é brincadeirinha)

E

Rafael Guerreiro:
carlucio:
Ola galera,

alguem conhece um metodo de raiz quadrada com iteração que nao seja o Math.sqrt

E o de raiz cubica tmbm .
Agradeço


E se você multiplicar a variável por ela mesma 2 vezes? É isso que você está querendo?

Rafael-san, você está confundindo “raiz quadrada” com “quadrado”. São coisas diferentes: uma dá debaixo da terra, como a cenoura, no País da Matemática; e o outro é o modo em que você vê o Sol se fizer algo (como um sequestro ou assassinato) e tiver o azar de ser preso.

Anime

Oi carlucio,

Não conheço,mas fiquei curiosa,por que não pode usar sqrt… :roll:

Da uma olhadinha aqui vai ajudar…http://programei.org/site/java/68-java/239-funcoes-matematicas-classe-math-java

E

Para quem precisa de calcular raiz quadrada com BigDecimal. É um pouco lento, mas…

package guj;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Raizes {

    private static BigDecimal seed (BigDecimal x) {
        int nDigits = x.abs().toBigInteger().toString().length();
        int n;
        if (nDigits % 2 == 1) {
            n = (nDigits - 1) / 2;
            return BigDecimal.valueOf(2).scaleByPowerOfTen(n);
        } else {
            n = (nDigits - 2) / 2;
            return BigDecimal.valueOf(6).scaleByPowerOfTen(n);
        }
    }
    
    public static BigDecimal sqrt (BigDecimal x, int n) {
        if (x.equals(BigDecimal.ZERO))
            return BigDecimal.ZERO;
        
        // x1 = x0 - f(x0) / f'(x0)
        // where f(x) = x^2 - q
        // f'(x) = 2x
        BigDecimal eps = BigDecimal.ONE.scaleByPowerOfTen(-n);
        BigDecimal x0, x1 = seed (x);
        do {
            x0 = x1;
            BigDecimal f = x0.pow(2).subtract(x);
            BigDecimal f_ = x0.add(x0); 
            x1 = x0.subtract(f.divide(f_, n, RoundingMode.HALF_EVEN));
        } while (x1.subtract(x0).abs().compareTo(eps) > 0);
        return x1;
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        //                                           1234567890123456789012345678901234567890123456789012345678
        System.out.println (sqrt (new BigDecimal ("3.1415926535897932384626433832795028841971693993751058209749"), 58));
        //                                         1.7724538509055160272981674833411451827975494561223871282137
        // Mostra:                                 1.7724538509055160272981674833411451827975494561223871282138
    }

}
Rafael_Guerreiro

entanglement:
Rafael Guerreiro:
carlucio:
Ola galera,

alguem conhece um metodo de raiz quadrada com iteração que nao seja o Math.sqrt

E o de raiz cubica tmbm .
Agradeço


E se você multiplicar a variável por ela mesma 2 vezes? É isso que você está querendo?

Rafael-san, você está confundindo “raiz quadrada” com “quadrado”. São coisas diferentes: uma dá debaixo da terra, como a cenoura, no País da Matemática; e o outro é o modo em que você vê o Sol se fizer algo (como um sequestro ou assassinato) e tiver o azar de ser preso.

HAHAHA! É verdade… Então basta ele dividir 1 pelo número da raiz e elevar a base, usando a potenciação…

Assim:

4 elevado a (1/2) é a mesma coisa que raiz 2 de (4 elevado a 1)

C

Galera,

é um trabalho da faculdade, ai nao pode user o math.sqrt

entanglement

Essa do bigdecimal é bem interessante,

porem gostaria de uma mais simples, onde eu pudesse explicar todo o codigo. esse do bigdecimal demoraria alem do prazo de entrega pra entende-la toda.

muito grato

E

Pois é, eu só implementei (usando BigDecimal) o algoritmo de Newton que está no primeiro link do Bezier Curve.
Cabe a você implementar o mesmíssimo algoritmo, mas usando double. OK?

Ravnus

Tentando reinventar a roda? =D

Eu não li os outros posts, mas pensa assim:

A raiz quadrada é o inverso da potência, se você quer fazer a raiz quadrada, faça um cálculo na mão e observe as fórmulas.

Frantic_Avenger

Espero que seja útil:
http://www.guj.com.br/posts/list/205972.java#1046056

<blockquote><div class="quote-author">Frantic Avenger:</div>Não sei se isso pode te ajudar mas…

Quando fiz um trabalho para calcular a raiz quadrada o professor tinha me avisado que a entrada de dados iriam ser números quadrados perfeitos, se for seu caso a raiz do número x é a soma dos valores de sua raiz nos primeiros números ímpares. Exemplo.

1 = 1 ( 1 número impar raiz 1)

4 = 1 + 3 (2 números ímpares raiz 2)

9 = 1 + 3 + 5 (3 números ímpares raiz 3)

16 = 1 + 3 + 5 + 7

25 = 1 + 3 + 5 + 7 + 9

…

121 = 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21

…

Espero ter ajudado. :wink:

Flw

C

Frantic.

essa sua formula da certo pra raizes exatas,

e no caso da raiz nao ser exata ?

pq é um projeto de uma calculadora, entao tem q tirar a raiz de tudo

Frantic_Avenger

Realmente isso que falei serve só para raízes exatas. Raízes não extas eu sinceramente não sei como fazer. Bom de qualquer forma boa sorte no seu desenvolvimento e se conseguir calcular a raíz desse jeito compartilha a informação :wink:
Flw

Marky.Vasconcelos

A formula de Newton que o entanglemente apresentou resolve.

C

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?

Frantic_Avenger

Olha cara o que encontrei no wikipedia:
Você pode usar o métodos dos números ímpares que mostrei anteriormente e depois usar o método ensinado no link.
http://pt.wikipedia.org/wiki/Raiz_quadrada

<edit> Como o Marky.Vasconcelos falou usa o código do entanglement que fica mais fácil </edit>

Flw

E

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?

Cruz credo, isso é que se chama de método tosco para achar uma raiz quadrada. Se valor for [telefone removido], quanto tempo vai ficar rodando esse algoritmo?

C

Realmente é um metodo bastante demorado…

mas é o mais simples que consegui achar.

Ouvi falar do metodo de Pell… Alguem sabe como implementar ?

E
gomesrod

entanglement:
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?

Cruz credo, isso é que se chama de método tosco para achar uma raiz quadrada. Se valor for [telefone removido], quanto tempo vai ficar rodando esse algoritmo?

É 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.

E

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 é [telefone removido], 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 :slight_smile:
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 .

E

Veja em:

http://www.sosmath.com/calculus/limcon/limcon07/limcon07.html

E

gomesrod:
entanglement:
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?

Cruz credo, isso é que se chama de método tosco para achar uma raiz quadrada. Se valor for [telefone removido], quanto tempo vai ficar rodando esse algoritmo?

É 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.

Continuo achando tosco. Vou achar tosco até a morte.

mario.fts

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 é [telefone removido], 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 :slight_smile:
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 .

hahaha praticamente uma busca binária.

E

Não é “praticamente uma busca binária”. O método de bissecção É UMA BUSCA BINÁRIA.

E

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…

E
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
    }
}
A

gomesrod:
entanglement:
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?

Cruz credo, isso é que se chama de método tosco para achar uma raiz quadrada. Se valor for [telefone removido], quanto tempo vai ficar rodando esse algoritmo?

É 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.

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…!!!

I

Pelo metodo de Pell

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;
	}

}
Luiz_Augusto_Prado
Criado 27 de outubro de 2010
Ultima resposta 21 de fev. de 2014
Respostas 32
Participantes 15