Jump to content

babylonian metodo da raiz quadrada...


Flames
 Share

Recommended Posts

Boas pessoal, tenho aqui um "problema" de interpretacao de um exercicio que acho que é resolvido (segundo os meus searchings pelo babylonian method):

Uma função numérica rápida para calcular uma raiz quadrada de um número x consiste

em utilizar o seguinte processo iterativo:

yn =1/2 * (yn-1 + x/yn-1)

sendo y0 uma estimativa para o valor da raiz quadrada (por exemplo, y0 = x/2). Numa

dada iteração da função, o erro existente no cálculo da raiz quadrada é dado pela

diferença entre os dois últimos valores calculados (isto é, yn-Yn-1). Pretende-se que

escreva um programa que calcule a raiz quadrada de um número dado. O programa

deverá ler o número para o qual se pretende fazer o cálculo e qual o número de casas

decimais corretas que a raiz deverá ter.

O que pretendo saber é o seguinte:

y0=x/2 e o yn-1 será eventualmente em cada ciclo por exemplo a primeira iteracao x/2-1 por ai fora...?

outro dado que nao percebi é o utilizador danos as casas decimais depois havemos de fazer algo como 10^( - casas decimais) isto é o erro existente para o calculo da raiz?

ou seja algo como um ciclo

while(yn-yn-1>10^(-casas decimais) {

/*entra na formula por assim dizer?*/

}

Eu sei que são duvidas um pouco estupidas mas sem entender isso fico na estaca zero... Quem me poder ajudar agradecia 😕

Link to comment
Share on other sites

#include <stdio.h>
#include <stdlib.h>
double mySqrt (int n, int numCasasDecimais);
int main()
{
    int Decimais,n;

    printf("Numero a calcular raiz\n");
    scanf("%d",&n);
    printf("casas decimais?\n");
    scanf("%d",&Decimais);
}
double mySqrt (int n, int numCasasDecimais){
    float x1; /*x1 em termos de contexto funciona como o Xn-1*/
    float x2; /*x2 em termos de contexto funciona como o Xn*/
    float w;

    x1=n/2;
    x2=((x1+(n/x1))/2);
    do
    {
        x1=x2;
        x2=((x1+(n/x1))/2);
        w=x2-x1;
    }
    while ((w)>decimaisPARACONVERTER AINDA );
    return x2;

}

Pessoal existe alguma forma de fazer a potencia sem usar a funcao pow? Quer dizer eu posso fazer a funcao pow usando iteracao como a raiz... mas nao existe outra forma de passar para casas decimais mais facilmente?

Btw ainda nao confirmei o codigo em cima...

Link to comment
Share on other sites

existe alguma forma de fazer a potencia sem usar a funcao pow?

A primeira coisa que me ocorre é usares uma "lookup table":

double prec1(int n) {
    static const int ltable[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
    if ((n < 0) || (n >= sizeof ltable / sizeof *ltable)) return 0; /* 0 indicates error */
    return 1.0 / ltable[n];
}

Mas tambem podes fazer divisoes sucessivas:

double prec2(int n) {
    double value = 1;
    if (n < 0) return 0; /* 0 indicates error */
    while (n--) value /= 10;
    return value;
}

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Link to comment
Share on other sites

double mySqrt (int n, int numCasasDecimais){
    float x1; /*x1 em termos de contexto funciona como o Xn-1*/
    float x2; /*x2 em termos de contexto funciona como o Xn*/
    float w;

Porque é que a função devolve um valor de tipo double, mas x1, x2, e w são do tipo float?

Sugestão: usa sempre double quando precisares de números com casas decimais, excepto se tiveres uma razão muito forte para usar outro tipo.

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Link to comment
Share on other sites

Tal como o pmg também aconselharia a fazeres algo tão simples como divisões sucessivas para achar o limiar pretendido. Toma atenção que deves comparar o valor absoluto da diferença com o erro que o utilizador pretende, caso contrário assim que tiveres x(n) < x(n-1) vais fazer x(n) - x(n-1) que é um valor negativo e sais do ciclo mesmo que o erro (i.e. o valor absoluto) seja maior do que o utilizador pretende.

Outra coisa que me intriga é o porquê de só aceitares inteiros na função. Esse método permite calcular a raíz quadrada de qualquer número positivo.

Só por curiosidade, o método babilónio não é mais que o método de newton aplicado à função f(y) = y^2  -  x, em que x é o número para o qual queres encontrar a raíz quadrada.

Não respondo a dúvidas por mensagem.

Link to comment
Share on other sites

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double mySqrt (int n, int numCasasDecimais);
double pot(int n);
int main()
{
    int Decimais,n;

    printf("Numero a calcular raiz\n");
    scanf("%d",&n);
    printf("casas decimais?\n");
    scanf("%d",&Decimais);
    mySqrt(n,Decimais);
}
double mySqrt (int n, int numCasasDecimais){
    double x1; /*x1 em termos de contexto funciona como o Xn-1*/
    double x2; /*x2 em termos de contexto funciona como o Xn*/
    double w;
    x1=n/2;
    x2=((x1+(n/x1))/2);
    do
    {
        x1=x2;
        x2=((x1+(n/x1))/2);
        w=x2-x1;
        if (w<0){
            w=-1*w;}
    }
    while (w>pot(numCasasDecimais));
    printf("%g",x2);
}

double pot(int n) {
    double value = 1;
    if (n < 0)
        return 0; /* 0 indicates error */
    while (n!=0) {
        value /= 10;
        n--;
        }
    return value;
}

Conclui assim pessoal a não ser que esteja errado btw nao usei a funcao abs (de forma a nao usar mesmo funcao nenhuma de C)...

  • Vote 1
Link to comment
Share on other sites

Conclui assim pessoal a não ser que esteja errado btw nao usei a funcao abs (de forma a nao usar mesmo funcao nenhuma de C)...

Tenho umas sugestões para ti:

1) não precisas do #include <stdlib.h> nem do #include <math.h>: não usas nenhuma função declarada nesses headers

2) O teu uso da função mySqrt() não usa o valor de retorno (que não especificas). Mete a função como void ... (ou dá-lhe um valor de retorno e usa-o)

3) a função main sem parametros fica mais correcta com void explicito (int main(void)) e fica melhor com um return para finalizar (obrigatorio em C89, assumido como return 0; em C99)

4) acrescenta um \n ao printf da função mySqrt() para coerencia com outros programas do Sistema Operativo

5) podes simplificar a função mySqrt() eliminando o cãlculo principal fora do ciclo: começa por inicializar x2 com n / 2 fora do ciclo. Lembra-te que o ciclo do ... while executa as instruções internas pelo menos uma vez.

Bom trabalho!

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Link to comment
Share on other sites

Tenho umas sugestões para ti:

1) não precisas do #include <stdlib.h> nem do #include <math.h>: não usas nenhuma função declarada nesses headers

2) O teu uso da função mySqrt() não usa o valor de retorno (que não especificas). Mete a função como void ... (ou dá-lhe um valor de retorno e usa-o)

3) a função main sem parametros fica mais correcta com void explicito (int main(void)) e fica melhor com um return para finalizar (obrigatorio em C89, assumido como return 0; em C99)

4) acrescenta um \n ao printf da função mySqrt() para coerencia com outros programas do Sistema Operativo

5) podes simplificar a função mySqrt() eliminando o cãlculo principal fora do ciclo: começa por inicializar x2 com n / 2 fora do ciclo. Lembra-te que o ciclo do ... while executa as instruções internas pelo menos uma vez.

Bom trabalho!

Obrigado pelas dicas 😕

Ps: usei o Do... while com essa intencao e nao a usei bahhhh -.-"

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.