TL; DR
Użyj jednego z nich dla potrzeb powszechnej konwersji
bigDecimal.setScale(0, RoundingMode.DOWN).intValueExact()
bigDecimal.toBigInteger().intValueExact()
Rozumowanie
Odpowiedź zależy od wymagań i od tego, jak odpowiesz na to pytanie.
- Czy
BigDecimal
potencjalnie będzie miał niezerową część ułamkową?
- Czy
BigDecimal
potencjalnie nie będzie pasować do Integer
zakresu?
- Czy chciałbyś, aby niezerowe części ułamkowe były zaokrąglane lub obcięte?
- Czy chciałbyś, aby niezerowe części ułamkowe były zaokrąglane?
Jeśli odpowiedziałeś nie na pierwsze 2 pytania, możesz po prostu użyć BigDecimal.intValueExact()
tego, co sugerowali inni i pozwolić, aby wybuchło, gdy wydarzy się coś nieoczekiwanego.
Jeśli nie masz 100% pewności co do pytania numer 2, zawszeintValue()
jest to zła odpowiedź.
Robię to lepiej
Skorzystajmy z następujących założeń na podstawie innych odpowiedzi.
- Nie przeszkadza nam utrata precyzji i obcięcie wartości, ponieważ to właśnie robią
intValueExact()
auto-boks
- Chcemy, aby wyjątek był wyrzucany, gdy
BigDecimal
jest większy niż Integer
zakres, ponieważ wszystko inne byłoby szalone, chyba że masz bardzo konkretną potrzebę zawijania, co dzieje się, gdy upuszczasz bity o wyższym porządku.
Biorąc pod uwagę te parametry, intValueExact()
zgłasza wyjątek, gdy nie chcemy, aby nasza część ułamkowa była różna od zera. Z drugiej strony intValue()
nie zgłasza wyjątku, gdy powinien, jeśli nasz BigDecimal
jest zbyt duży.
Aby uzyskać to, co najlepsze z obu światów, zaokrąglij BigDecimal
pierwszy, a następnie przekonwertuj. Ma to również tę zaletę, że zapewnia większą kontrolę nad procesem zaokrąglania.
Spock Groovy Test
void 'test BigDecimal rounding'() {
given:
BigDecimal decimal = new BigDecimal(Integer.MAX_VALUE - 1.99)
BigDecimal hugeDecimal = new BigDecimal(Integer.MAX_VALUE + 1.99)
BigDecimal reallyHuge = new BigDecimal("10000000000000000000000000000000000000000000000")
String decimalAsBigIntString = decimal.toBigInteger().toString()
String hugeDecimalAsBigIntString = hugeDecimal.toBigInteger().toString()
String reallyHugeAsBigIntString = reallyHuge.toBigInteger().toString()
expect: 'decimals that can be truncated within Integer range to do so without exception'
'' + decimal.intValue() == decimalAsBigIntString
'' + decimal.setScale(0, RoundingMode.DOWN).intValueExact() == decimalAsBigIntString
and: 'truncated decimal that cannot be truncated within Integer range throw conversionOverflow exception'
and: 'truncated decimal that cannot be truncated within Integer range throw conversionOverflow exception'
and: 'if using Java 8, BigInteger has intValueExact() just like BigDecimal'
}