BigDecimal grenzwertig

25/11/2014 - 17:16 von Patrick Roemer | Report spam
Hallo,

mit JDK1.8.0_25 (JDK1.7 aber wohl auch):

<snip>
BigDecimal bd = new BigDecimal(new BigInteger("1"), Integer.MIN_VALUE);
System.err.println(bd.toString()); // 1E+2147483648
new BigDecimal(bd.toString()); // -> NumberFormatException
</snip>

Aehnliche Spaesse kriegt man auch mit anderen, "krummeren"
unscaledValue/scaled-Kombinationen hin. Kann mir das jemand erklaeren?
Warum '+'? Ist das ein bekannter Bug? Oder verstehe ich BigDecimal
einfach nicht?

Viele Gruesse,
Patrick
 

Lesen sie die antworten

#1 Wanja Gayk
25/11/2014 - 19:37 | Warnen spam
In article <m52a0j$1v6$, Patrick Roemer
() says...

Hallo,

mit JDK1.8.0_25 (JDK1.7 aber wohl auch):

<snip>
BigDecimal bd = new BigDecimal(new BigInteger("1"), Integer.MIN_VALUE);
System.err.println(bd.toString()); // 1E+2147483648
new BigDecimal(bd.toString()); // -> NumberFormatException
</snip>

Aehnliche Spaesse kriegt man auch mit anderen, "krummeren"
unscaledValue/scaled-Kombinationen hin. Kann mir das jemand erklaeren?
Warum '+'? Ist das ein bekannter Bug? Oder verstehe ich BigDecimal
einfach nicht?



Ich nehme an, dass das ein Bug ist, der sich auch in bd.toPlainString()
findet.
In bd.toPlainString(), was eine Arithemtic Exception "overflow" erzeugt,
hast du folgenden Code:

..
if(this.scale<0) { // No decimal point
if(signum()==0) {
return "0";
}
int tailingZeros = checkScaleNonZero((-(long)scale));

und in "checkScaleNonZero" steht:

int asInt = (int)val; //val ist dein "(-(long)scale)"
if (asInt != val) {
throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
}
return asInt;

Die Werte hier:

val: 2147483648
asInt: -2147483648

Damit wàre der Overflow in BigDecimal#toPlainString() erklàrt.

Wenn man dem Konstruktor new BigDecimal(String) folgt, kommmst du
irgendwann an diese Stelle im Java-8-Source, wo deine Exception
geschmissen wird:

exp = parseExp(in, offset, len);
// Next test is required for backwards compatibility
if ((int) exp != exp) // overflow
throw new NumberFormatException(); // <-- boom!
...

Sieht für mein naives Auge, ohne lànger darüber nachzudenkenm aus, als
wàre der Test für den Overflow für Integer.MinValue schlicht falsch.

Gruß,
-Wanja-

..Alesi's problem was that the back of the car was jumping up and down
dangerously - and I can assure you from having been teammate to
Jean Alesi and knowing what kind of cars that he can pull up with,
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

Ähnliche fragen