Jelikoz 1.0/2.0*(xi+y/xi) ma tu blbou vlastnost, ze se tam musi delit, a deleni jako nebrat, da se vyuzit pro vypocet odmocniny reseni rovnice 1/y*y - A = 0 (Newtonovou metodou), potom je iteracni vztah y_{i+1} = 1.0/2.0*y_i*(3-A*y_i*y_i), pomoci ktereho se da urcit hodnota 1/sqrt(A) a pak sqrt(A) = A * 1/sqrt(A).
Presnost vypoctu zavisi na volbe y_0, ta musi byt v rozmezi 0 < y_0 < sqrt(3/a) a vlastne celkovy pocet iteraci k dosazeni presneho vysledku zavisi na volbe pocatecniho odhadu (muzeme ho trefit od oka vypoctem nebo mit odhady predpocitane v tabulce).
#include <stdio.h>
#include <math.h>
double sqrt_step(float y, float A){
return 1.0/2.0*y*(3-A*y*y);
}
int main(){
double vstup = 10000;
double yi = ((3/vstup) / 2); // odhad ma byt 0 < y0 < sqrt(3/vstup);
int i;
double sqr=1.0/sqrt(vstup); // počitadlo iterac
for( i = 0; i < 20; i++){
yi = sqrt_step(yi, vstup);
printf("%d\t%11.5f\t%11.5f\t%10.2f%%\n",
i+1,
yi, // vypočtená hodnota
fabs(yi - sqr), // absolutní chyba
100.0f * fabs(yi-sqr) /sqr ); // relativní chyba }
}
printf("sqrt(%11.5f) = %11.5f\n", vstup, vstup * yi);
}
To vypada zajimave, diky za uverejneni. Jen se chci zeptat - neexistuje tam vice reseni te rovnice? (jeste jsem tu funkci 1/y*y-A nezkoumal, ale mam dojem, ze ma aspon dva koreny). Chyba - mam aspon ten dojem - klesa trosku pomaleji, ale ta eliminace deleni IMHO stoji za to.
Rekl bych, ze zavisi na volbe pocatecniho y_0. Ten rozsah 0 < y_0 < sqrt(3/A) je vybran obecne tak, ze
to vyjde kladne doufam pro vsechna A > 0. Ale vyzkousej dosadit jiny pocatecni odhad, treba 0.005 pro A = 10000, spravny vysledek po 5 iteracich. O duvod vic pouzit predpocitanou tabulku (klidne muze byt i v ROMce daneho FPU)