JavaRush /Blog Java /Random-PL /Zaokrąglanie liczb w Javie

Zaokrąglanie liczb w Javie

Opublikowano w grupie Random-PL
Liczby zmiennoprzecinkowe (float, double) są używane podczas obliczania wyrażeń wymagających precyzji dziesiętnej. Wysoka dokładność jest często wymagana w księgowości i innych operacjach obliczeniowych. Zaokrąglanie liczb w Javie - 1Ale czy zawsze potrzebujemy długiego „ogona” liczb po przecinku? Może wystarczy nam dokładność trzech części rzeczywistych? I jesteśmy z tej opcji zadowoleni, jak prawidłowo wykonać zaokrąglenie? Właśnie o tym dzisiaj porozmawiamy: przyjrzymy się sposobom zaokrąglania liczb w Javie .

Format ciągu

Jako pierwszą metodę przyjrzymy się zaokrąglaniu podwójnie:
double value = 34.766674;
String result = String.format("%.3f",value);
System.out.print(result);//  34,767
W rezultacie sformatujemy naszą liczbę zmiennoprzecinkową 34766674 z dokładnością do 3 miejsc po przecinku , ponieważ w instrukcji formatowania podaliśmy trzy miejsca po przecinku „%.3f. Z kolei %f podczas formatowania ciągu wskazuje typ zmiennoprzecinkowy Numbers, który zawiera typ danych double i float w Javie. W powyższym przykładzie wypisujemy wynikową wartość do konsoli. Teraz pytanie brzmi: jak możemy to skrócić? To proste: musisz użyć printf, co z kolei to format + print.W rezultacie poprzedni nasz przykład zostałby zredukowany do:
double value = 34.766674;
System.out.printf("%.3f",value);
Oprócz tej metody instancja out klasy PrintStream posiada także metodę format, która działa podobnie:
double value = 34.766674;
System.out.format("%.3f",value);
Zaokrąglanie następuje w trybie HALF_UP - w kierunku liczby bliższej tej obcinanej (do 0 lub 10). Jeżeli liczby te są jednakowo odległe (w przypadku 5), wówczas przeprowadza się zaokrąglanie w górę. Przykład:
String firstResult = String.format("%.3f",7.0004);// 7,000
String secondResult = String.format("%.3f",7.0005);// 7,001
String thirdResult = String.format("%.3f",7.0006);// 7,001
Tryby zaokrąglania omówimy bardziej szczegółowo poniżej. Zaokrąglanie liczb w Javie - 2

Format dziesiętny

Inną opcją jest użycie klasy DecimalFormat . Został zaprojektowany do formatowania dowolnej liczby w Javie, niezależnie od tego, czy jest to liczba całkowita, czy liczba zmiennoprzecinkowa. Kiedy tworzymy instancję DecimalFormat, możemy przekazać jej ciąg formatujący. Wskaże, ile miejsc po przecinku należy sformatować dla danych wejściowych. Tak wyglądałby nasz przykład przy użyciu DecimalFormat :
double value = 34.766674;
DecimalFormat decimalFormat = new DecimalFormat( "#.###" );
String result = decimalFormat.format(value);
System.out.print(result);//34,767
Linia #.### to wzór wskazujący, że formatujemy przekazaną wartość z dokładnością do 3 miejsc po przecinku. Aby zmienić wzorzec po utworzeniu obiektu DecimalFormat, możesz skorzystać z jego metod ApplyPattern i ApplyLocalizedPattern :
DecimalFormat decimalFormat = new DecimalFormat("#.###");
decimalFormat.applyPattern("#.#");
decimalFormat.applyLocalizedPattern("#.#####");
Ale dzisiaj mówimy o zaokrąglaniu, prawda? Podczas obcinania liczby z miejscami dziesiętnymi poza określonym wzorcem funkcja DecimalFormat zaokrągla liczbę w górę, jeśli ostatnia obcięta liczba jest większa niż 5. A co, jeśli liczba wynosi 5? Okazuje się, że znajduje się dokładnie pośrodku pomiędzy najbliższymi liczbami całkowitymi. Co wtedy? W takim przypadku brany jest pod uwagę poprzedni numer. Jeśli jest parzysty, wykonywane jest zaokrąglanie:
DecimalFormat decimalFormat = new DecimalFormat("#.###");
String result = decimalFormat.format(7.4565);
System.out.println((result));// 7,457
Jeśli jest nieparzysty, nie jest wykonywany:
DecimalFormat decimalFormat = new DecimalFormat("#.###");
String result = decimalFormat.format(7.4575);
System.out.println((result));// 7,457
Istnieje niewielka różnica pomiędzy formatowaniem liczb zmiennoprzecinkowych za pomocą funkcji String.format() i DecimalFormat.format(). Pierwsza z nich zawsze wypisuje zera końcowe, nawet jeśli nie ma części ułamkowej. Np:
String firstResult = String.format("%.3f", 7.000132);
System.out.println((firstResult)); // 7.000

DecimalFormat decimalFormat = new DecimalFormat("#.###");
String secondResult = decimalFormat.format(7.000132);
System.out.println((secondResult));  // 7
Jak widzimy, podczas formatowania liczby 7,000132 do trzech miejsc po przecinku, metoda format() String zwróci 7,000, podczas gdy metoda format() DecimalFormat wyświetli 7. Oznacza to, że możesz wybrać String.format() lub DecimalFormat. ) w zależności od tego, czy potrzebujesz zer końcowych, czy nie. Stosując metody opisane powyżej otrzymaliśmy wynik w postaci ciągu znaków. Przyjrzyjmy się sposobom odzyskania dokładnie wartości liczbowych.

Matematyka

Nie sposób nie wspomnieć o specjalnej klasie przystosowanej do różnorodnych operacji arytmetycznych na liczbach – Math . Zaokrąglanie liczb w Javie - 3Klasa ta posiada również metody zaokrąglania, jednakże w odróżnieniu od już opisanych, nie pozwalają one na ustawienie określonej liczby miejsc po przecinku, a raczej zaokrąglają do liczby całkowitej:
  • Funkcja Math.ceil() zaokrągla w górę do najbliższej liczby całkowitej, ale zwraca nie liczbę całkowitą, ale liczbę podwójną:

    double value = 34.777774;
    double result = Math.ceil(value);
    System.out.println((result)); //35.0

    Nawet jeśli mamy 34,0000000, po użyciu Math.ceil nadal otrzymamy 35,0.

    Math.floor() zaokrągla w dół do najbliższej liczby całkowitej, zwracając również wynik jako podwójny:

    double value = 34.777774;
    double result = Math.floor(value);
    System.out.println((result)); //34.0

    Ponownie, nawet jeśli mamy wartość 34,999999999, to po użyciu Math.floor otrzymamy 34,0.

  • Math.round() - zaokrągla do najbliższej liczby całkowitej i daje wynik int:

    double value = 34.777774;
    int result = Math.round(value);
    System.out.println((result)); //35

    Jeśli nasza liczba wynosi 34,5, jest ona zaokrąglana do 35, natomiast jeśli jest nieco mniejsza niż 34,499, liczba jest obcinana do 34.

    Aby nie tylko odciąć całą część rzeczywistą, ale uregulować ten proces do określonej liczby miejsc po przecinku i jednocześnie zaokrąglić, liczbę mnoży się przez 10^n (10 do potęgi n), gdzie n jest równa liczbie niezbędnych miejsc po przecinku. Następnie stosuje się metodę klasy Math do zaokrąglania i ponownego dzielenia przez 10^n:

    double value = 34.777774;
    double scale = Math.pow(10, 3);
    double result = Math.ceil(value * scale) / scale;
    System.out.println((result)); //34.778

    Math.pow — przyjmuje dwa argumenty. Pierwsza to liczba, druga to potęga, do której należy ją podnieść.

Zaokrąglanie za pomocą BigDecimal

BigDecimal to klasa, która pozwala pracować z liczbami zmiennoprzecinkowymi. W szczególności jego główną cechą jest to, że może przechowywać liczby ułamkowe o dowolnej długości (to znaczy nie ma ograniczeń co do zakresu liczby). Ponadto w tej klasie przechowywane są różne metody przetwarzania arytmetycznego, w tym zaokrąglania. Klasę tego obiektu można utworzyć, ustawiając konstruktor na double, string wyświetlający liczbę zmiennoprzecinkową, double i MathContext itd. MathContext jest kombinacją RoundingMode i liczby opisującej całkowitą liczbę cyfr w wyszukiwanej wartości. Zasady zaokrąglania RoundingMode: DOWN - zaokrąglanie do zera. UP — zaokrąglanie od zera. SUFIT - zaokrąglenie w stronę dodatniej nieskończoności. PODŁOGA - zaokrąglenie w stronę ujemnej nieskończoności. HALF_UP – Zaokrągla do „najbliższego sąsiada”, jeśli obaj sąsiedzi nie są w równej odległości (to znaczy, gdy zaokrąglana liczba wynosi 5). W takim przypadku przeprowadzane jest zaokrąglanie. HALF_DOWN - zaokrąglenie w kierunku „najbliższego sąsiada”. Jeśli obaj sąsiedzi nie są w równej odległości, w tym przypadku zaokrąglij w dół. HALF_EVEN – Zaokrągla do „najbliższego sąsiada”, jeśli obaj sąsiedzi nie są w równej odległości. W tym przypadku zaokrąglij do parzystego sąsiada (jak w DecimalFormat opisanym powyżej). NIEKONIECZNE — używane do potwierdzenia, że ​​żądana operacja dała poprawny wynik. Dlatego zaokrąglanie nie jest wymagane. Przykład:
MathContext context = new MathContext(5, RoundingMode.HALF_UP);
double value = 34.777554;
BigDecimal result = new BigDecimal(value, context);
System.out.println(result); //34.778
Oprócz możliwości ustawienia reguły zaokrąglania w konstruktorze, BigDecimal umożliwia ustawienie trybu zaokrąglania po utworzeniu instancji. Aby to zrobić, użyj metody setScale , w której musisz ustawić liczbę miejsc po przecinku i zasady zaokrąglania:
double value = 34.777554;
BigDecimal result = new BigDecimal(value);
result = result.setScale(3, RoundingMode.DOWN);
System.out.println(result); //34.777
BigDecimal ma również wewnętrzne zmienne int przeznaczone do ustawiania trybu zaokrąglania ( ROUND_DOWN , ROUND_CEILING , ROUND_FLOOR ...). Są to reguły zaokrąglania podobne do tych przedstawionych w klasie RoundingMode i są podobnie używane w setScale :
BigDecimal result = new BigDecimal(value);
result = result.setScale(3, BigDecimal.ROUND_DOWN);
Więcej o klasie BigDecimal przeczytasz w tym artykule .
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION