Answers:
您将致电myBigDecimal.intValueExact()
(或仅致电intValue()
),如果您丢失了信息,它甚至会引发异常。返回一个int,但是自动装箱会解决这个问题。
intValueExact()
是一个很好的建议;它是在1.5加入
intValue()
除非您百分百地肯定自己的电话号码在该Integer
范围内,否则打电话是危险的。
您可以保证BigDecimal
绝对不会包含大于的值Integer.MAX_VALUE
吗?
如果是,那么这里是您的代码调用intValue
:
Integer.valueOf(bdValue.intValue())
TL; DR
使用其中之一满足通用转换需求
//Java 7 or below
bigDecimal.setScale(0, RoundingMode.DOWN).intValueExact()
//Java 8
bigDecimal.toBigInteger().intValueExact()
推理
答案取决于要求是什么以及如何回答这些问题。
BigDecimal
潜在的分数部分将为非零吗?BigDecimal
可能不适合的Integer
范围是多少?如果您对前两个问题的回答为“否”,则可以BigDecimal.intValueExact()
按照他人的建议使用,并在发生意外情况时将其炸毁。
如果你不是绝对100%的信心问题编号2,然后intValue()
是一直错误的答案。
变得更好
让我们基于其他答案使用以下假设。
intValueExact()
自动装箱BigDecimal
大于Integer
范围时引发异常,因为除非您有特殊的需要,即当您丢弃高位时发生回绕,否则任何其他事情都会令人发疯。给定这些参数,intValueExact()
如果我们不希望小数部分为非零,则抛出异常。另一方面,intValue()
如果我们BigDecimal
太大,则不应该抛出异常。
要获得两全其美,BigDecimal
请先将其四舍五入,然后再进行转换。这还具有使您对舍入过程有更多控制的好处。
Spock Groovy测试
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()
}
好吧,您可以致电BigDecimal.intValue()
:
将此BigDecimal转换为int。此转换类似于Java语言规范中定义的从double到short的原始缩元转换:此BigDecimal的任何小数部分都将被丢弃,并且如果结果“ BigInteger”太大而无法容纳int,则仅将低位-返回32位。请注意,此转换会丢失有关此BigDecimal值的整体大小和精度的信息,并返回带有相反符号的结果。
然后Integer.valueOf(int)
,如果您使用的是Java的最新版本,则可以显式调用或让自动装箱完成。
以下应该可以解决问题:
BigDecimal d = new BigDecimal(10);
int i = d.intValue();
您是否尝试过调用BigInteger#intValue()?