TL; DR
Evrensel dönüşüm ihtiyaçları için bunlardan birini kullanın
//Java 7 or below
bigDecimal.setScale(0, RoundingMode.DOWN).intValueExact()
//Java 8
bigDecimal.toBigInteger().intValueExact()
muhakeme
Cevap, gereksinimlerin ne olduğuna ve bu soruları nasıl cevapladığınıza bağlıdır.
- Will
BigDecimal
potansiyel sıfır olmayan kesirli kısmı var?
- Will
BigDecimal
potansiyel sığmayan Integer
aralık?
- Sıfır olmayan kesirli parçaların yuvarlatılmış veya kesilmiş olmasını ister misiniz?
- Sıfır olmayan kesirli parçaların yuvarlatılmasını nasıl istersiniz?
İlk 2 soruya hayır cevabını verdiyseniz, BigDecimal.intValueExact()
başkalarının önerdiği gibi kullanabilir ve beklenmedik bir şey olduğunda patlamasına izin verebilirsiniz .
Eğer 2. sorusuna hakkında kesinlikle% 100 emin değilseniz, o zaman intValue()
olduğu hep yanlış cevap.
Daha iyi yapmak
Diğer cevaplara göre aşağıdaki varsayımları kullanalım.
- Hassasiyeti kaybetmekte ve değeri kırpmakta sorunumuz yok çünkü bu,
intValueExact()
otomatik boks
- Aralıktan
BigDecimal
daha büyük olduğunda bir istisna atılmasını istiyoruz Integer
çünkü yüksek sıralı bitleri düşürdüğünüzde meydana gelen sarmaya çok özel bir ihtiyaç duymadığınız sürece başka her şey çılgınca olacaktır.
Bu parametreler göz önüne alındığında, intValueExact()
kesirli bölümümüz sıfır değilse, istemediğimizde bir istisna atar. Öte yandan, intValue()
bizim BigDecimal
çok büyükse, olması gerektiği zaman bir istisna yapmaz .
Her iki dünyanın da en iyisini elde etmek için BigDecimal
ilkini tamamlayın , sonra dönüştürün. Bu aynı zamanda size yuvarlama işlemi üzerinde daha fazla kontrol sağlama avantajına sahiptir.
Spock Groovy Testi
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'
//GOOD: Truncates without exception
'' + decimal.intValue() == decimalAsBigIntString
//BAD: Throws ArithmeticException 'Non-zero decimal digits' because we lose information
// decimal.intValueExact() == decimalAsBigIntString
//GOOD: Truncates without exception
'' + decimal.setScale(0, RoundingMode.DOWN).intValueExact() == decimalAsBigIntString
and: 'truncated decimal that cannot be truncated within Integer range throw conversionOverflow exception'
//BAD: hugeDecimal.intValue() is -2147483648 instead of 2147483648
//'' + hugeDecimal.intValue() == hugeDecimalAsBigIntString
//BAD: Throws ArithmeticException 'Non-zero decimal digits' because we lose information
//'' + hugeDecimal.intValueExact() == hugeDecimalAsBigIntString
//GOOD: Throws conversionOverflow ArithmeticException because to large
//'' + hugeDecimal.setScale(0, RoundingMode.DOWN).intValueExact() == hugeDecimalAsBigIntString
and: 'truncated decimal that cannot be truncated within Integer range throw conversionOverflow exception'
//BAD: hugeDecimal.intValue() is 0
//'' + reallyHuge.intValue() == reallyHugeAsBigIntString
//GOOD: Throws conversionOverflow ArithmeticException because to large
//'' + reallyHuge.intValueExact() == reallyHugeAsBigIntString
//GOOD: Throws conversionOverflow ArithmeticException because to large
//'' + reallyHuge.setScale(0, RoundingMode.DOWN).intValueExact() == reallyHugeAsBigIntString
and: 'if using Java 8, BigInteger has intValueExact() just like BigDecimal'
//decimal.toBigInteger().intValueExact() == decimal.setScale(0, RoundingMode.DOWN).intValueExact()
}