Vis*_*hal 126 java integer casting bigdecimal
我有Hibernate方法,它返回一个BigDecimal.我有另一个API方法,我需要传递该数字但它接受Integer作为参数.我无法更改两种方法的返回类型或变量类型.
现在如何将BigDecimal转换为Integer并将其传递给第二个方法?
有没有办法解决这个问题?
wil*_*ood 199
你会打电话myBigDecimal.intValueExact()(或只是intValue()),如果丢失信息,它甚至会抛出异常.返回一个int但是autoboxing会处理这个问题.
Ano*_*non 32
你能保证BigDecimal永远不会包含大于的值Integer.MAX_VALUE吗?
如果是,那么这是您的代码调用intValue:
Integer.valueOf(bdValue.intValue())
Run Code Online (Sandbox Code Playgroud)
Sne*_*kse 18
TL; DR
使用其中一种来满足通用转换需求
//Java 7 or below
bigDecimal.setScale(0, RoundingMode.DOWN).intValueExact()
//Java 8
bigDecimal.toBigInteger().intValueExact()
Run Code Online (Sandbox Code Playgroud)
推理
答案取决于要求是什么以及如何回答这些问题.
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()
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 17
好吧,你可以打电话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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
283927 次 |
| 最近记录: |