Jak w temacie jak policzyć pierwiastek n-tego stopnia bez użycia metod z Math? Zielonego pojęcia nie mam.
A google nie działał ?
https://pl.wikipedia.org/wiki/Algorytm_obliczania_pierwiastka_n-tego_stopnia
Potęge całkowitą (która jest potrzebna w trakcie obliczeń) dasz radę chyba policzyć.
Pamiętam z jakiejś starej książki do nauki Turbo Pascala 7.0, że działanie x do potęgi y
można przedstawić w postaci exp(y * ln(x))
, czyli e^(y*ln(x))
(gdzie e
to liczba Eulera, a ln
to logarytm naturalny).
W Wikipedii znalazłem wzory:
Napisałem klasę z potrzebnymi funkcjami matematycznymi. Skupiałem się na prostocie, a nie na wydajności (wydajność można bardzo poprawić). Nie sprawdzam poprawności argumentów funkcji. Wybrałem C#, czyli najlepszy język programowania na świecie (polecał go nawet wielki informatyk Bill Gates).
class MyMath
{
static double Ln(double x, int n)
{
if (n == 0)
return 0;
else
return PowerInt(((x - 1) / x), n) / n + Ln(x, n - 1);
}
static double Exp(double x, int n)
{
if (n == 0)
return 1;
else
return PowerInt(x, n) / Factorial(n) + Exp(x, n - 1);
}
static int Factorial(int x)
{
if (x == 0)
return 1;
else
return x * Factorial(x - 1);
}
static double PowerInt(double x, int n)
{
if (n == 0)
return 1;
else
return x * PowerInt(x, n - 1);
}
static double PowerReal(double x, double y)
{
return Exp(y * Ln(x, 1000), 25);
}
public static double Power(double x, double y)
{
return PowerInt(x, (int)y) * PowerReal(x, y - (int)y);
}
}
Parametr n
w funkcjach Exp
i Ln
oznacza stopień precyzji. Teoretycznie powinien być nieskończonością, ale mój komputer na to nie pozwala.
Pierwiastek liczby to jest potęga tej liczby o wykładniku odwrotnym do stopnia jej pierwiastka, czyli np. pierwiastek siódmego stopnia z trzech
można uzyskać wywołując funkcję MyMath.Power(3, 1/7d)
, która zwraca wynik 1.16993081275869
.
Mam coś takiego:
class zad1 {
public static double abs(double a)
{
if(a < 0)
return a * (-1);
else
return a;
}
public static double pow(double a, double n)
{
if(n == 0)
return 1;
else
return a * pow(a, --n);
}
public static double sqrt(double a, double n)
{
double result = a;
double tmp = pow(result, (n-1));
double e = 0.00000000001;
while(abs(a - tmp * result) >= e)
{
result = (1/n) * ((n-1) * result + (a/tmp));
tmp = pow(result, n-1);
}
return result;
}
public static void main(String[] args){
if(args.length > 1)
{
double sqrt1 = sqrt(Double.parseDouble(args[0]), Double.parseDouble(args[1]));
System.out.println("Pierwiastek z " + args[0] + " stopnia " + args[1] + " wynosi: " + sqrt1);
}
else
System.out.println("Brak argumentow");
}
}
zawsze możesz zgadywać.
pseudokod:
// x - liczba do spierwiastkowania
// acc - dokładność
// g - zgadywany pierwiastek
// r - różnica między g^2 i szukanym x
// rand( a, b ) - libczba losowa większa od a, mniejsza od b
// abs ( x ) - wartość bezwzględna
sqrt( x, acc ) {
min = 0
max = x
while( true ) {
g = rand( min, max );
r = x - g*g;
if( abs( r ) < acc )
return g
if( r < 0 )
min = g
else
max = g
}
}
pewnie mniej optymalne od metody analitycznej, choć w połączeniu z programowaniem dynamicznym, kto wie. Róznie to może być.
Do tego co juz Tobie napisano, mogę dodać, e możesz skorzystać z metody kolejnych przybliżeń.
Jeśli ma być to pierwiastek z liczby całkowitej i wynikiem ma być liczba całkowitą, można skorzystać z artykułu kolegi Krashana http://teleinfo.pb.edu.pl/krashan/articles/pierwiastkowanie/ kod w asemblerze, ale wykorzystać można wszędzie.