0

While playing around with generative testing I came across the following:

import org.scalacheck.Properties
import org.scalacheck.Prop.forAll

object BigDecimalSpec extends Properties("BigDecimal") {
  property("apply") = forAll(Arbitrary.arbBigDecimal.arbitrary) {
    x => x == BigDecimal(x.toString())
  }
}

fails with:

! String.apply: Exception raised on property evaluation.
> ARG_0: 0E+2147483648
> Exception: java.lang.NumberFormatException: null
java.math.BigDecimal.<init>(BigDecimal.java:511)
java.math.BigDecimal.<init>(BigDecimal.java:757)
scala.math.BigDecimal$.apply(BigDecimal.scala:119)
scala.math.BigDecimal$.apply(BigDecimal.scala:117)

Why wouldn't BigDecimal be able to translate a decimal String representation created by itself?

Kaarel Nummert
  • 989
  • 8
  • 20
  • This BigDecimal value is weird, it's actually zero, written rather convolutedly. How was this value constructed? – laune Feb 11 '15 at 18:27
  • @laune, it was constructed by `Arbitrary.arbBigDecimal.arbitrary` which is a `scalacheck` generator for `scala.math.BigDecimal` – Kaarel Nummert Feb 11 '15 at 18:42
  • Perhaps this code doesn't try to stay within "reasonable" bounds. A number of this size isn't realistic - compare it to the number of atoms in the universe... – laune Feb 11 '15 at 18:49
  • Since tests test the unreasonable by definition, how about this: https://issues.scala-lang.org/browse/SI-9143 – som-snytt Feb 11 '15 at 20:39

1 Answers1

2

This is by definition. From BigDecimal's javadoc:

The exponent consists of the character 'e' ('\u0065') or 'E' ('\u0045') followed by one or more decimal digits. The value of the exponent must lie between -Integer.MAX_VALUE (Integer.MIN_VALUE+1) and Integer.MAX_VALUE, inclusive.

Emphasis by me, and Integer.MAX_VALUE = 2147483647.

laune
  • 31,114
  • 3
  • 29
  • 42