Obiekt Math w JavaScript to niepozorny pas narzędziowy tego języka. Nigdy go nie instancjonujesz. Nigdy go nie importujesz. Po prostu istnieje w każdym środowisku uruchomieniowym, gotowy do obsługi wszystkiego – od zaokrąglania wartości piksela po generowanie losowego rzutu kostką. Ponieważ Math jest obiektem statycznym, każda metoda i właściwość znajduje się bezpośrednio w przestrzeni nazw. Piszesz Math.PI, a nie new Math().PI. Taki wybór projektowy upraszcza sprawę, ale oznacza również, że obiekt ten posiada kilka „ostrych krawędzi”, które warto zrozumieć, zanim zaczniesz polegać na nim w logice produkcyjnej.

Statyczny obiekt bez konstruktora

Większość wbudowanych obiektów JavaScript wymaga utworzenia instancji. Wywołujesz new Date() lub new Array(). Math odmawia współpracy. Został zaprojektowany jako przestrzeń nazw powiązanych funkcji i stałych, które operują na prymitywnym typie Number. Wywołaj Math.sqrt(16), a otrzymasz 4. Spróbuj użyć słowa kluczowego new, a silnik wyrzuci TypeError. Ten wzorzec pozwala utrzymać czystość pamięci i sygnalizuje, że Math jest czysto funkcyjny. Przyjmuje dane wejściowe, zwraca wyniki i niczego nie mutuje.

Istnieje jedno surowe ograniczenie, o którym należy pamiętać: Math pracuje ze standardowymi liczbami IEEE 754. Nie współpracuje z BigInt. Przekażesz BigInt do Math.round() lub Math.abs(), otrzymasz TypeError. Jeśli Twoja aplikacja operuje na 64-bitowych liczbach całkowitych lub większych, musisz dokonać konwersji w dół lub obsługiwać arytmetykę za pomocą natywnych operatorów BigInt.

Stałe, których faktycznie używasz

Obiekt Math udostępnia kilka stałych numerycznych, które chronią Cię przed wpisywaniem na sztywno tzw. magicznych liczb.

  • Math.PI to znane 3.14159..., niezbędne wszędzie tam, gdzie pojawiają się okręgi, trygonometria lub konwersja stopni na radiany.
  • Math.E to liczba Eulera, wynosząca około 2.718. Pojawia się w krzywych wzrostu wykładniczego, obliczeniach procentu składanego i skalach logarytmicznych.
  • Math.SQRT2 to pierwiastek kwadratowy z dwóch, około 1.414. Jest przydatny, gdy potrzebujesz przekątnej kwadratu lub chcesz znormalizować wektory w prostej geometrii.
  • Math.LN2 to logarytm naturalny z 2, około 0.693. Zobaczysz go w algorytmach zajmujących się drzewami binarnymi, entropią informacji lub analizie złożoności czasowej wymagającej obliczeń logarytmicznych o podstawie 2.

Wartości te są liczbami zmiennoprzecinkowymi o podwójnej precyzji. Ponieważ są to właściwości, a nie metody, uzyskujesz do nich dostęp bez nawiasów.

Zaokrąglanie, znaki i wartości bezwzględne

Najczęstsze zadania związane z Math polegają na porządkowaniu liczb. JavaScript oferuje cztery metody zaokrąglania, które nie zachowują się identycznie, zwłaszcza po opuszczeniu obszaru liczb dodatnich.

Math.abs(x) zwraca wartość bezwzględną liczby. Podaj -42, a otrzymasz 42. Jest to przydatne, gdy interesuje Cię odległość, a nie kierunek. Pomyśl o porównywaniu znaczników czasu, obliczaniu różnic przesunięcia w interfejsie użytkownika lub sprawdzaniu, czy zgadywana wartość mieści się w marginesie błędu.

Math.round(x) to klasyczne zaokrąglanie szkolne. Przyjmuje najbliższą liczbę całkowitą, zaokrąglając wartości połowowe w górę do następnej dodatniej liczby całkowitej. Zatem 4.4 staje się 4, a 4.5 staje się 5.

Math.ceil(x) zawsze zaokrągla w górę do następnej liczby całkowitej. 4.1 staje się 5, a -4.9 staje się -4. To ostatnie zaskakuje ludzi. Ponieważ -4 jest większe niż -4.9 na osi liczbowej, ceil przesuwa się w stronę zera dla liczb ujemnych.

Math.floor(x) działa odwrotnie. Zawsze zaokrągla w dół. 4.9 staje się 4, a -4.1 staje się -5. Jeśli stronicujesz wyniki wyszukiwania lub przydzielasz bloki pamięci o stałym rozmiarze, floor jest zazwyczaj tym, czego potrzebujesz.

Math.trunc(x) całkowicie odcina część dziesiętną, pozostawiając jedynie część całkowitą. W efekcie przesuwa się w stronę zera, niezależnie od znaku. 4.9 staje się 4, a -4.9 staje się -4. Jeśli przenosisz logikę z języków, które rzutują liczby zmiennoprzecinkowe na całkowite poprzez ucinanie, to będzie Twój przyjaciel.

Na koniec Math.sign(x) informuje, po której stronie zera znajduje się wartość. Zwraca 1 dla liczb dodatnich, -1 dla ujemnych, 0 dla dodatniego zera, -0 dla ujemnego zera oraz NaN dla wszystkiego, co nie jest liczbą. Jest to zwięzły sposób na rozgałęzianie logiki w zależności od kierunku bez pisania łańcucha instrukcji if-else.

Generowanie liczb losowych

Math.random() generuje pseudolosową liczbę zmiennoprzecinkową z zakresu od 0 (włącznie) do 1 (wyłącznie). Nie jest ona bezpieczna kryptograficznie, więc nie używaj jej do generowania haseł, tworzenia tokenów ani do czegokolwiek, co wiąże się z prawdziwymi pieniędzmi.