1. Funkcje trygonometryczne w Javie

Kiedy wcześniej studiowaliśmy zaokrąglanie liczb, zapoznaliśmy się z Mathklasą i niektórymi jej metodami. Przyjrzymy się teraz tej klasie bardziej szczegółowo.

Jak sama nazwa wskazuje, Mathklasa zawiera metody operacji matematycznych najczęściej używanych przez programistów. Oto najciekawsze z nich:

metoda Opis
double sin(double d)
Zwraca sinus kąta dw radianach
double cos(double d)
Zwraca cosinus kąta dw radianach
double tan(double d)
Zwraca tangens kąta dw radianach
double asin(double d)
Zwraca arcus sinus
double acos(double d)
Zwraca arcus cosinus
double atan(double d)
Zwraca arcus tangens
double sinh(double d)
Zwraca sinus hiperboliczny
double cosh(double d)
Zwraca cosinus hiperboliczny
double tanh(double d)
Zwraca tangens hiperboliczny

Metody , i przyjmują kąt wyrażony w radianach. Aby przekonwertować kąt ze stopni na radiany i odwrotnie, klasa oferuje dwie specjalne metody:Math.sin()Math.cos()Math.tan()Math

metoda Opis
double toRadians(double angdeg)
Konwertuje kąt ze stopni na radiany
double toDegrees(double angrad)
Konwertuje kąt z radianów na stopnie

Nawiasem mówiąc, oprócz metod, Mathklasa posiada również dwie zmienne stałe (pola statyczne klasy):

Stały Opis
double Math.PI
Stała „Pi” jest równa3.141592653589793
double Math.E
Stała „E” jest równa2.718281828459045

Wszystkie te funkcje mogą ci się bardzo przydać, jeśli zdecydujesz się pisać własne gry, pracować z grafiką lub po prostu obliczać długość ścieżki na mapie.

Na przykład, jeśli chcesz obliczyć sin(45°), wykonaj to w następujący sposób:

Math.sin( Math.toRadians(45) )

Oto przykład:

public class Main
{
   public static int N = 10;

   public static void drawValue(double y)
   {
     int value = (int) (y * N) + N;
     for (int i = 0; i < 2 * N; i++)
     {
       char c = i == N ? '|': '.';
       if (i == value)
         c = '*';
       System.out.print(c);
     }
     System.out.println();
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 10 * N; i++)
     {
       double x = i * 1.0 / N;
       double y = Math.sin(x);
       drawValue(y);
     }
   }
}


2. Funkcje algebraiczne w Javie

W większości przypadków programistom wystarczy matematyka ze szkoły średniej: nawet sinusy i cosinusy są bardzo rzadko spotykane w kodzie. Najczęściej są one potrzebne podczas pracy z grami, mapami czy silnikami gier. 90% programistów nigdy się z tym nie spotyka.

Ale oprócz geometrii programiści czasami muszą używać funkcji algebraicznych. I oczywiście Mathklasa zawiera te najczęstsze:

metoda Opis
double sqrt(double a)
pierwiastek kwadratowy za
double cbrt(double a)
pierwiastek sześcienny za
double pow(double a, double b)
potęgowanie:ab
double exp(double a)
wykładniczy (liczba Eulera podniesiona do potęgi):ea
double log(double a)
logarytm naturalny z a:ln(a)
double log10(double a)
logarytm o podstawie 10 z a:log10(a)
double log1p(double x)
logarytm naturalny z x + 1:ln(x + 1)
double expm1(double x)
ex-1

Jeśli chcesz uzyskać pierwiastek kwadratowy lub sześcienny z liczby, metody sqrt(a)i cbrt(a)są do Twojej dyspozycji.

Pierwiastek kwadratowy można obliczyć w następujący sposób:

Math.sqrt(2)

Jeśli chcesz uzyskać pierwiastek z wyższej potęgi, użyj metody potęgowania: ado potęgi ¼jest czwarty pierwiastek itd.

Math.pow(2, 0.25)

W przypadku logarytmów i wykładników istnieją metody log(a)(logarytm naturalny) i exp(x)(wykładniczy). Aby obliczyć logarytm o podstawie 10, mamy log10(a).

Jeśli chcesz, aby logarytm liczby bbył podstawą a, użyj tej prostej formuły:loga(b) = ln(b) / ln(a)

Przydatne metody

Jeśli wykonujesz obliczenia z bardzo małymi wartościami x, dwie ostatnie funkcje — log1p()i expm1()— mogą ci się przydać.

Podczas dodawania bardzo małych i bardzo dużych doublezmiennych często okazuje się, że bardzo małe wartości są po prostu ignorowane (odrzucane) jako nieistotne. W rzeczywistości stanie się tak, jeśli użyjesz metod log()i exp(). Aby rozwiązać ten problem, programiści wymyślili funkcje, które zwracają tylko „małą znaczącą część”

Przykład:

Załóżmy, że chcesz obliczyć logarytm naturalny z 1 + x, gdzie xjest . Nie możesz po prostu przekazać tej liczby metodzie , ponieważ jeśli dodasz i , otrzymasz . jest tak małą liczbą, że zostanie całkowicie odrzucona po dodaniu liczb.10-20log()110-20110-20

Ponieważ matematyka często polega na obliczaniu log()liczb bliskich 1, programiści wymyślili sposób obejścia tego problemu: zamiast przekazywania samej liczby do metody, przekaż tylko jej różnicę z 1.



3. Minimum i maksimum

Dwie bardziej przydatne funkcje to min(a, b)i max(a, b). Jak zapewne już się domyśliłeś, pierwszy zwraca minimum dwie liczby:

Math.min(a, b)

A druga zwraca maksymalnie dwie liczby:

Math.max(a, b)

Po co nam te funkcje, skoro zawsze można napisać, ifa nawet użyć operatora trójskładnikowego (a < b ? a: b)?

Wszystko zależy od czytelności kodu. Czasami twój kod jest przeładowany ifinstrukcjami i chcesz użyć bardziej zwartej notacji. Porównajmy:

Kod Opis
int x = 0;
if (x-5+y*20 < x*x+y*y)
   x = x-5+y*20;
else
   x = x*x+y*y;
Używanie if-elseinstrukcji (najdłuższy sposób jej napisania)
int x = x-5+y*20 < x*x+y*y ? x-5+y*20 : x*x+y*y;
Korzystanie z operatora trójskładnikowego Wady:
- nieporęczny kod
- obliczenia są wykonywane dwukrotnie
int a = x-5+y*20;
int b = x*x+y*y;
int x = a < b ? a : b;
To świetny sposób na napisanie tego, ale jest trochę zbędny
int x = Math.min(x-5+y*20, x*x+y*y);
Właśnie 🙂

4. Minimum i maksimum kilku liczb

Jest jeszcze jeden świetny sposób na użycie metod min()i max().

Aby obliczyć minimum (lub maksimum) kilku liczb lub zmiennych. Wykonywanie zagnieżdżonych wywołań tych metod jest bardzo wygodne.

Oto jak znaleźć minimum 3 liczby:

Math.min(a, Math.min(b, c))

Więc co? To bardzo wygodne: oblicz minimum dwóch liczb, a następnie zwróć minimum tej liczby i trzecią liczbę.

Minimum cztery liczby uzyskuje się w ten sam sposób:

Math.min(a, Math.min(b, Math.min(с, d)))

To powiedziawszy, możemy napisać tę formułę nieco jaśniej:

Math.min(Math.min(a, b), Math.min(c, d))

To wszystko działa tak samo dla max()metody.

Użycie if-elseoperatora lub operatora trójskładnikowego sprawiłoby, że te fragmenty kodu byłyby nieco bardziej kłopotliwe. Ale użycie metod min()i max()jest po prostu idealne.