Jak zaokrąglić liczbę do N miejsc dziesiętnych w Javie

1. Przegląd

W tym krótkim artykule przyjrzymy się, jak zaokrąglić liczbę do n miejsc dziesiętnych w Javie.

2. Liczby dziesiętne w Javie

Java udostępnia dwa typy pierwotne, których można używać do przechowywania liczb dziesiętnych: zmiennoprzecinkowe i podwójne . Double to typ używany domyślnie:

double PI = 3.1415;

Jednak obu typów nie należy nigdy używać do określania dokładnych wartości , takich jak waluty. W tym celu, a także do zaokrąglania, możemy użyć klasy BigDecimal .

3. Formatowanie liczby dziesiętnej

Jeśli chcemy tylko wydrukować liczbę dziesiętną z n cyframi po przecinku, możemy po prostu sformatować wyjściowy ciąg:

System.out.printf("Value with 3 digits after decimal point %.3f %n", PI); // OUTPUTS: Value with 3 digits after decimal point 3.142

Alternatywnie możemy sformatować wartość za pomocą klasy DecimalFormat :

DecimalFormat df = new DecimalFormat("###.###"); System.out.println(df.format(PI));

DecimalFormat pozwala nam jawnie ustawić zachowanie zaokrąglania, dając większą kontrolę nad danymi wyjściowymi niż używana powyżej String.format () .

4. Zaokrąglanie liczb podwójnych za pomocą BigDecimal

Aby zaokrąglić podwójne s do n miejsc dziesiętnych, możemy napisać metodę pomocniczą :

private static double round(double value, int places) { if (places < 0) throw new IllegalArgumentException(); BigDecimal bd = new BigDecimal(Double.toString(value)); bd = bd.setScale(places, RoundingMode.HALF_UP); return bd.doubleValue(); }

W tym rozwiązaniu należy zwrócić uwagę na jedną ważną rzecz - przy konstruowaniu BigDecimal ; musimy zawsze używać BigDecimal (String) konstruktora . Zapobiega to problemom z reprezentowaniem niedokładnych wartości.

Możemy osiągnąć to samo, korzystając z biblioteki Apache Commons Math:

 org.apache.commons commons-math3 3.5 

Najnowszą wersję można znaleźć tutaj.

Po dodaniu biblioteki do projektu możemy skorzystać z metody Precision.round () , która przyjmuje dwa argumenty - wartość i skalę:

Precision.round(PI, 3);

Domyślnie używa tej samej metody zaokrąglania HALF_UP , co nasza metoda pomocnicza. Dlatego wyniki powinny być takie same.

Zauważ, że możemy zmienić zachowanie zaokrąglania, przekazując żądaną metodę zaokrąglania jako trzeci parametr.

5. Zaokrąglanie podwójnych z DoubleRounder

DoubleRounder to narzędzie w bibliotece decimal4j. Zapewnia szybką i bezużyteczną metodę zaokrąglania podwójnych od 0 do 18 miejsc po przecinku.

Bibliotekę możemy pobrać (najnowszą wersję można znaleźć tutaj) dodając zależność do pom.xml :

 org.decimal4j decimal4j 1.0.3 

Teraz możemy po prostu użyć:

DoubleRounder.round(PI, 3);

Jednak DoubleRounder zawodzi w kilku scenariuszach, na przykład:

System.out.println(DoubleRounder.round(256.025d, 2)); // OUTPUTS: 256.02 instead of expected 256.03

6. Metoda Math.round ()

Innym sposobem zaokrąglania liczb jest użycie metody Math.Round ().

W tym przypadku możemy kontrolować n liczbę miejsc dziesiętnych mnożąc i dzieląc przez 10 ^ n :

public static double roundAvoid(double value, int places) { double scale = Math.pow(10, places); return Math.round(value * scale) / scale; }

Ta metoda nie jest zalecana, ponieważ obcina wartość . W wielu przypadkach wartości są nieprawidłowo zaokrąglane:

System.out.println(roundAvoid(1000.0d, 17)); // OUTPUTS: 92.23372036854776 !! System.out.println(roundAvoid(260.775d, 2)); // OUTPUTS: 260.77 instead of expected 260.78

Dlatego ta metoda została tutaj wymieniona wyłącznie w celach edukacyjnych.

7. Wnioski

W tym krótkim samouczku omówiliśmy różne techniki zaokrąglania liczb do n miejsc dziesiętnych.

Możemy po prostu sformatować dane wyjściowe bez zmiany wartości lub możemy zaokrąglić zmienną za pomocą metody pomocniczej. Omówiliśmy również kilka bibliotek, które zajmują się tym problemem.

Kod użyty podczas dyskusji można znaleźć na GitHub.