BigDecimal を返す Hibernate メソッドがあります。その番号を渡す必要がある別の API メソッドがありますが、パラメーターとして整数を受け入れます。両方のメソッドの戻り値の型または変数の型を変更できません。
BigDecimal を Integer に変換して 2 番目のメソッドに渡す方法は?
これから抜け出す方法はありますか?
BigDecimal を返す Hibernate メソッドがあります。その番号を渡す必要がある別の API メソッドがありますが、パラメーターとして整数を受け入れます。両方のメソッドの戻り値の型または変数の型を変更できません。
BigDecimal を Integer に変換して 2 番目のメソッドに渡す方法は?
これから抜け出す方法はありますか?
を呼び出すmyBigDecimal.intValueExact()
(または単にを呼び出すintValue()
) と、情報が失われる場合は例外がスローされます。それはintを返しますが、オートボクシングがそれを処理します。
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()
すると、小数部分がゼロ以外の場合に例外をスローしたくない場合に例外がスローされます。一方、 ourが大きすぎるintValue()
場合は例外をスローする必要がありますが、例外をスローしません。BigDecimal
両方の長所を活かすには、BigDecimal
最初の 1 つを四捨五入してから変換します。これには、丸めプロセスをより細かく制御できるという利点もあります。
スポックの 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 値の全体的な大きさと精度に関する情報が失われるだけでなく、反対の符号の結果が返される可能性があることに注意してください。
十分に新しいバージョンの Java を使用している場合は、明示的に呼び出すInteger.valueOf(int)
か、自動ボクシングに任せることができます。
次のトリックを行う必要があります。
BigDecimal d = new BigDecimal(10);
int i = d.intValue();
BigInteger#intValue()を呼び出してみましたか?
BigDecimal#intValue()を参照してください
上記の方法ではうまくいかないことがわかりました。JTable からセル値を取得していましたが、double や int などにキャストできませんでした。私の解決策:
Object obj = getTable().getValueAt(row, 0);
行 0 は常に数値になります。これがまだスクロールしている人に役立つことを願っています!