1. ホーム
  2. java

Java BigDecimalのオーバーフローの可能性のあるバグ

2023-08-09 22:29:56

質問

あるコードで境界条件をテストしていたのですが、そのコードには BigDecimal を含むコードの境界条件をテストしていました。 BigDecimal が文字列で初期化されるとき "1e2147483647" で初期化された場合、予期せぬ振る舞いをします。の間の値を持っているようだ。 01e-2147483647 . を呼び出そうとすると intValue() を呼び出すと NegativeArraySizeException . 注意すべきは 2147483647 は私のシステム上の整数の最大値であることに注意してください。私は何か間違ったことをしているのでしょうか、それとも、この問題は BigDecimal ?

BigDecimal test = new BigDecimal("1e2147483647");

test.compareTo(new BigDecimal(0));  //Returns 1
test.compareTo(new BigDecimal("1e-2147483647"));  //Returns -1
test.intValue();  //Throws NegativeArraySizeException

どのように解決するのですか?

いいえ、あなたは正当なバグを持っているように見えます。このバグは JDK7 に存在しますが、JDK8 では修正されています。あなたの値は正しく BigDecimal として正しく表現でき、正しく動作するはずですが、そうではありません。

をトレースすると のソースコードをたどると BigDecimal は、2585行目にある this.precision() が 1 であり this.scale-2147483647 . this.precision() - this.scale であるためオーバーフローし、以下のオーバーフローは正しく処理されません。

このバグ は修正されました。 によって JDK8 では で引き算をすることで long 算術 .