1. Zaokrąglanie liczb rzeczywistych

Jak już omówiliśmy, gdy do zmiennej przypisujemy liczbę rzeczywistą, intto zawsze jest ona zaokrąglana w dół do liczby całkowitej – jej część ułamkowa jest po prostu odrzucana.

Ale możesz łatwo wyobrazić sobie sytuację, w której ułamek musi zostać zaokrąglony po prostu do najbliższej liczby całkowitej lub nawet w górę. Co zrobić w tej sytuacji?

W tym i wielu podobnych przypadkach w Javie istnieje klasa Math, która ma metody round(), ceil(), floor().


metodaMath.round()

Metoda Math.round()zaokrągla liczbę do najbliższej liczby całkowitej:

long x = Math.round(real_number)

Ale, jak mówią, jest pewien niuans: wynikiem tej metody jest liczba całkowita long(nie int). Liczby rzeczywiste mogą być bardzo duże, więc programiści Javy zdecydowali się użyć największego typu liczb całkowitych, jaki ma Java, long.

Dlatego, aby przypisać wynik do zmiennej typu int, programista musi wyraźnie powiedzieć kompilatorowi, że godzi się na ewentualną utratę danych (nagle liczba nie mieści się w typie int).

int x = (int) Math.round(real_number)

Przykłady:

Zespół Wynik
int x = (int) Math.round(4.1);
4
int x = (int) Math.round(4.5);
5
int x = (int) Math.round(4.9);
5

metodaMath.ceil()

Metoda Math.ceil()zaokrągla liczbę w górę do liczby całkowitej , przykłady:

Zespół Wynik
int x = (int) Math.ceil(4.1);
5
int x = (int) Math.ceil(4.5);
5
int x = (int) Math.ceil(4.9);
5

metodaMath.floor()

Metoda Math.floor()zaokrągla liczbę w dół do liczby całkowitej , przykłady:

Zespół Wynik
int x = (int) Math.floor(4.1);
4
int x = (int) Math.floor(4.5);
4
int x = (int) Math.floor(4.9);
4

Chociaż, aby zaokrąglić liczbę w dół do liczby całkowitej , łatwiej będzie użyć prostego operatora rzutowania - (int):

Zespół Wynik
int x = (int) 4.9
4

Jeśli masz trudności z zapamiętaniem tych poleceń, krótka lekcja angielskiego pomoże ci:

  • Math- matematyka
  • Round- kółko/okrągło
  • Ceiling- sufit
  • Floor- podłoga


2. Urządzenie liczb zmiennoprzecinkowych

Typ doublemoże przechowywać wartości do . Tak gigantyczny rozpiętość wartości (w porównaniu do type ) wynika z faktu, że typ (like ) ma zupełnie inną strukturę w porównaniu do typów integer. Każda zmienna typu zawiera dwie liczby: pierwsza nazywana jest mantysą , a druga wykładnikiem .-1.7*10308+1.7*10308intdoublefloatdouble

Powiedzmy, że mamy liczbę 123456789i przechowujemy ją w zmiennej typu double. Następnie liczba zostanie przekonwertowana do postaci , a dwie liczby zostaną zapisane wewnątrz typu - i . „Znacząca część liczby” (mantysa) jest podświetlona na czerwono, stopień na niebiesko.1.23456789*108double234567898

Takie podejście pozwala przechowywać zarówno bardzo duże liczby, jak i bardzo małe. Lecz odkąd rozmiar liczby jest ograniczony do 8 bajtów (64 bity) i część bitów służy do przechowywania stopnia (oraz znaku liczby i znaku stopnia), ograniczona jest maksymalna długość mantysy do 15 cyfr .

Jest to bardzo uproszczony opis budowy liczb rzeczywistych, pełniejszy można znaleźć pod linkiem .


3. Utrata precyzji podczas pracy z liczbami rzeczywistymi

Podczas pracy z liczbami rzeczywistymi należy zawsze pamiętać, że liczby rzeczywiste nie są dokładne . Błędy zaokrągleń , błędy konwersji dziesiętnych na binarne będą się pojawiać zawsze , i wreszcie najczęstsza – utrata precyzji przy dodawaniu/odejmowaniu liczb o zbyt różnych wymiarach.

Ta ostatnia sytuacja jest najbardziej nieoczekiwaną sytuacją dla nowicjuszy w programowaniu.

Jeśli odejmiemy od liczby , otrzymamy ponownie .1/109109109

Odejmowanie liczb o zbyt różnych wymiarach Wyjaśnienie
1000000000.000000000;
-         0.000000001;
 1000000000.000000000;
Druga liczba jest za mała i jej znacząca część jest ignorowana (wyszarzona). 15 cyfr znaczących jest podświetlonych na pomarańczowo .

Cóż mogę powiedzieć, programowanie to nie matematyka.


4. Niebezpieczeństwo porównywania liczb rzeczywistych

Inne niebezpieczeństwo czyha na programistów podczas porównywania liczb rzeczywistych. Ponieważ podczas pracy z tymi liczbami mogą gromadzić się błędy zaokrągleń, wtedy możliwe są sytuacje, w których liczby rzeczywiste powinny być równe, ale nie są równe. I odwrotnie: liczby nie powinny być równe, ale są równe.

Przykład:

Zespół Wyjaśnienie
double a = 1000000000.0;
double b = 0.000000001;
double c = a - b;
Zmienna a będzie miała wartość 1000000000.0
Zmienna c będzie miała wartość 1000000000.0
(liczba w zmiennej b jest za mała)

W powyższym przykładzie ai cnie muszą być równe, ale są.

Lub weź inny przykład:

Zespół Wyjaśnienie
double a = 1.00000000000000001;
double b = 1.00000000000000002;
Zmienna a będzie miała wartość 1.0
Zmienna b będzie miała wartość1.0

5. Ciekawostka ostrictfp

Java ma specjalne słowo kluczowe (strictfp ścisłe zmiennoprzecinkowe ) , którego nie ma w innych językach programowania . A czy wiesz, dlaczego tego potrzebujesz? Pogarsza to dokładność pracy z liczbami rzeczywistymi. Historia jego pojawienia się jest w przybliżeniu następująca:

Twórcy Javy:
Naprawdę chcemy, aby Java była bardzo popularna, a programy Java działały na jak największej liczbie urządzeń. Dlatego w specyfikacji maszyny Java napisaliśmy, że wszystkie programy powinny działać tak samo na wszystkich typach urządzeń !
Twórcy procesora Intel:
Chłopaki, ulepszyliśmy nasze procesory, a teraz wszystkie liczby rzeczywiste w procesorze będą reprezentowane nie przez 8, ale przez 10 bajtów. Więcej bajtów oznacza więcej cyfr znaku. Co to znaczy? Zgadza się: teraz Twoje obliczenia naukowe będą jeszcze dokładniejsze!
Naukowcy i wszyscy zaangażowani w ultraprecyzyjne obliczenia:
Fajny! Dobrze zrobiony. Dobre wieści.
Twórcy Javy:
Nie, nie, nie, chłopaki. Powiedzieliśmy: wszystkie programy Java powinny działać tak samo na wszystkich urządzeniach . Wymuś wyłączenie możliwości używania 10-bajtowych liczb rzeczywistych w procesorach Intela.
Teraz wszystko znowu jest super! Nie dziękuj.
Naukowcy i wszyscy zaangażowani w ultraprecyzyjne obliczenia:
Czy jesteś tam całkowicie szalony? Anu szybko zwrócił wszystko tak, jak było!
Twórcy Javy:
Chłopaki, to dla waszego dobra! Wyobraź sobie: wszystkie programy Java działają w ten sam sposób na wszystkich urządzeniach . Cóż, to jest fajne!
Naukowcy i wszyscy zaangażowani w ultraprecyzyjne obliczenia:
NIE. Wcale nie fajne. Wszystko zostało szybko zwrócone! A może wiemy, gdzie umieścimy Twoją Javę?
Twórcy Javy:
Um. Dlaczego po prostu nie powiedziałeś. Oczywiście wrócimy.
Przywrócono możliwość korzystania ze wszystkich funkcji fajnych procesorów.
Przy okazji. Specjalnie dodaliśmy również słowo do języka strictfp: jeśli napiszesz je przed nazwą funkcji, cała praca z liczbami rzeczywistymi wewnątrz tej funkcji będzie równie zła na wszystkich urządzeniach !