Zaokrąglanie BigDecimal do * zawsze * ma dwa miejsca po przecinku

217

Próbuję zaokrąglić wartości BigDecimal w górę, do dwóch miejsc po przecinku.

używam

BigDecimal rounded = value.round(new MathContext(2, RoundingMode.CEILING));
logger.trace("rounded {} to {}", value, rounded);

ale nie robi tego, co chcę konsekwentnie:

rounded 0.819 to 0.82
rounded 1.092 to 1.1
rounded 1.365 to 1.4 // should be 1.37
rounded 2.730 to 2.8 // should be 2.74
rounded 0.819 to 0.82

Nie obchodzą mnie cyfry znaczące, chcę tylko dwóch miejsc po przecinku. Jak to zrobić za pomocą BigDecimal? A może jest jeszcze inna klasa / biblioteka, która lepiej się do tego nadaje?

Brad Mace
źródło
9
Jeśli naprawdę chcesz zaokrąglić, skorzystaj z RoundingMode.HALF_UP
Gilbert Le Blanc

Odpowiedzi:

401
value = value.setScale(2, RoundingMode.CEILING)
Louis Wasserman
źródło
19
To rzeczywiście działa tak, jak chcę. Czy różnica po prostu round()działa z cyframi znaczącymi, podczas gdy setScaledziała ze stałą liczbą miejsc dziesiętnych, czy jest coś więcej?
Brad Mace
44
Użyj funkcji RoundingMode.HALF_UP, aby wykonać „typcal rounding”. Czyli 1.111 daje 1.11 [SUFIT daje 1.12]
Grzegorz Dev
5
Dzięki za RoundingMode.HALF_UP. Zgodnie z dokumentacją jest to metoda zaokrąglania powszechnie nauczana w szkołach - tego potrzebowałem.
srebrny
1
Uważaj, jeśli twoje wartości mogą być ujemne, jak w aplikacji księgowej. Może być konieczne użycie RoundingMode.UP zamiast CEILING
Dale
1
Dlaczego setScale(...)działa zobacz BigDecimal setScale i okrągły .
Jason Law