Wątek przeniesiony 2017-10-12 06:54 z Java przez Koziołek.

Pierwiastek bez pow()

0

Jak w temacie jak policzyć pierwiastek n-tego stopnia bez użycia metod z Math? Zielonego pojęcia nie mam.

3

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

0

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:

title
title

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.

0

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");	

	}
}

0

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

0

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1