回答:
あなたはmyBigDecimal.intValueExact()
(または単にintValue()
)呼び出し、情報を失うと例外をスローします。これはintを返しますが、オートボクシングがそれを処理します。
intValueExact()
良いお勧めです。1.5に追加されました
intValue()
番号が範囲内であることを確信して100%人生に賭けない限り、電話は危険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
範囲?最初の2つの質問に「いいえ」と答えた場合はBigDecimal.intValueExact()
、他の人が提案したとおりに使用し、予期しないことが起こったときにそれを爆発させることができます。
質問2について完全に100%自信がない場合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に収まらない場合は、低-order 32ビットが返されます。この変換では、このBigDecimal値の全体的な大きさと精度に関する情報が失われ、反対の符号の結果が返される可能性があることに注意してください。
Integer.valueOf(int)
十分に新しいバージョンのJavaを使用している場合は、明示的に呼び出すか、自動ボクシングで自動的に実行させることができます。
BigInteger#intValue()を呼び出してみましたか?
BigDecimal#intValue()を参照してください