Scala BigDecimal无法转换由其自身创建的十进制字符串表示形式

时间:2015-02-11 18:11:57

标签: java scala bigdecimal

在玩生成测试时,我遇到了以下情况:

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())
  }
}

失败了:

! 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)

为什么BigDecimal无法翻译自己创建的小数String表示?

2 个答案:

答案 0 :(得分:2)

这是定义。来自BigDecimal的javadoc:

指数由角色&#39; e组成。 (&#39; \ u0065&#39;)或&#39; E&#39; (&#39; \ u0045&#39;)后跟一个或多个十进制数字。指数的值必须介于-Integer.MAX_VALUE(Integer.MIN_VALUE + 1)和 Integer.MAX_VALUE,之间。

我强调,Integer.MAX_VALUE = 2147483647。

答案 1 :(得分:0)

因为这就是ScalaCheck正在做的事情:

scala> import java.math.{BigInteger => BI, BigDecimal => BD, MathContext => MC}
import java.math.{BigInteger=>BI, BigDecimal=>BD, MathContext=>MC}

scala> new BD(BI.ZERO, Int.MaxValue, MC.UNLIMITED)
res3: java.math.BigDecimal = 0E-2147483647

scala> new BD(BI.ZERO, Int.MaxValue + 1, MC.UNLIMITED)
res4: java.math.BigDecimal = 0E+2147483648

scala> new BD(res4.toString)
java.lang.NumberFormatException
  at java.math.BigDecimal.<init>(BigDecimal.java:491)
  at java.math.BigDecimal.<init>(BigDecimal.java:383)
  at java.math.BigDecimal.<init>(BigDecimal.java:806)
  ... 33 elided

但我不是BigDecimal的专家,而且我不知道投票网站上此评论的背景:

            // Next test is required for backwards compatibility
            if ((int)exp != exp)         // overflow
                throw new NumberFormatException();

哎呀,我想要的只是随机数据...