143

BigDecimal を返す Hibernate メソッドがあります。その番号を渡す必要がある別の API メソッドがありますが、パラメーターとして整数を受け入れます。両方のメソッドの戻り値の型または変数の型を変更できません。

BigDecimal を Integer に変換して 2 番目のメソッドに渡す方法は?

これから抜け出す方法はありますか?

4

8 に答える 8

224

を呼び出すmyBigDecimal.intValueExact()(または単にを呼び出すintValue()) と、情報が失われる場合は例外がスローされます。それはintを返しますが、オートボクシングがそれを処理します。

于 2010-10-28T14:01:37.753 に答える
34

BigDecimalに より大きい値が決して含まれないことを保証できますInteger.MAX_VALUEか?

はいの場合、コード呼び出しは次のintValueとおりです。

Integer.valueOf(bdValue.intValue())
于 2010-10-28T13:59:33.427 に答える
25

TL;DR

普遍的な変換のニーズには、これらのいずれかを使用してください

//Java 7 or below
bigDecimal.setScale(0, RoundingMode.DOWN).intValueExact()
//Java 8    
bigDecimal.toBigInteger().intValueExact()

推論

答えは、要件が何であるか、およびこれらの質問にどのように答えるかによって異なります。

  • BigDecimalゼロ以外の小数部を持つ可能性はありますか?
  • 範囲BigDecimalに収まらない可能性がありますか?Integer
  • 0 以外の小数部分を丸めるか切り捨てるか。
  • ゼロ以外の小数部分をどのように丸めますか?

最初の 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()
}
于 2015-03-11T18:12:29.697 に答える
20

さて、あなたは呼び出すことができますBigDecimal.intValue()

この BigDecimal を int に変換します。この変換は、Java 言語仕様で定義されている double から short への縮小プリミティブ変換に似ています。この BigDecimal の小数部分は破棄され、結果の "BigInteger" が大きすぎて int に収まらない場合は、下位のみが変換されます。 -order 32 ビットが返されます。この変換により、この BigDecimal 値の全体的な大きさと精度に関する情報が失われるだけでなく、反対の符号の結果が返される可能性があることに注意してください。

十分に新しいバージョンの Java を使用している場合は、明示的に呼び出すInteger.valueOf(int)か、自動ボクシングに任せることができます。

于 2010-10-28T14:01:05.050 に答える
9

次のトリックを行う必要があります。

BigDecimal d = new BigDecimal(10);
int i = d.intValue();
于 2010-10-28T14:00:06.973 に答える
1

BigInteger#intValue()を呼び出してみましたか?

于 2010-10-28T14:02:17.890 に答える
0

BigDecimal#intValue()を参照してください

于 2010-10-28T14:00:03.567 に答える
-4

上記の方法ではうまくいかないことがわかりました。JTable からセル値を取得していましたが、double や int などにキャストできませんでした。私の解決策:

Object obj = getTable().getValueAt(row, 0);

行 0 は常に数値になります。これがまだスクロールしている人に役立つことを願っています!

于 2016-04-29T21:18:37.087 に答える