Flames Posted February 26, 2012 at 04:25 AM Report Share #441181 Posted February 26, 2012 at 04:25 AM 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 More sharing options...
Flames Posted February 26, 2012 at 05:15 AM Author Report Share #441182 Posted February 26, 2012 at 05:15 AM #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 More sharing options...
pmg Posted February 26, 2012 at 11:02 AM Report Share #441185 Posted February 26, 2012 at 11:02 AM 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 More sharing options...
pmg Posted February 26, 2012 at 11:28 AM Report Share #441186 Posted February 26, 2012 at 11:28 AM 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 More sharing options...
pedrosorio Posted February 26, 2012 at 12:14 PM Report Share #441188 Posted February 26, 2012 at 12:14 PM 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 More sharing options...
Flames Posted February 26, 2012 at 03:39 PM Author Report Share #441203 Posted February 26, 2012 at 03:39 PM #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)... 1 Report Link to comment Share on other sites More sharing options...
pmg Posted February 26, 2012 at 04:19 PM Report Share #441210 Posted February 26, 2012 at 04:19 PM 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 More sharing options...
Flames Posted February 26, 2012 at 07:16 PM Author Report Share #441234 Posted February 26, 2012 at 07:16 PM 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now