大数字的BigDecimal比例

时间:2017-03-06 14:27:49

标签: java math bigdecimal

我正在尝试理解BigDecimal的比例,但它很奇怪,我无法理解为什么。以下是几个例子:

Double d = new Double(1000000d);
int scale = new BigDecimal(d.toString()).scale();

此示例中的比例将为1,这对我来说是正确的。 d.toString()的结果是“1000000.0”。

Double d = new Double(10000000d);
int scale = new BigDecimal(d.toString)).scale();

此示例中的比例为-6。有谁能解释为什么? d.toString()的结果是“1.0E7”。

我认为数字位数会导致这种情况,但如果我去了:

Double d = new Double(11111111d);
int scale = new BigDecimal(d.toString()).scale();

预计比例为-8但突然为0。 d.toString()的结果是“1.1111111E7”。

在阅读Javadoc of scale()之后,这些不同的尺度对我来说毫无意义:

  

返回此BigDecimal的比例。如果为零或正数,则比例是小数点右侧的位数。如果是负数,则将数字的未缩放值乘以10来表示比例的否定。例如,比例为-3表示未缩放的值乘以1000。

我非常感谢BigDecimal在数字很大时的行为。

提前致谢!

2 个答案:

答案 0 :(得分:3)

您获得的比例是具有一定重要性的小数位数

  • 1000000d - > 1000000.0 - > 0:点右边的数字没有意义,结果为0;
  • 10000000d - > 1.0E7 - > -6:点右边的数字有重要意义,好像你将权力归一化十,你得到6个零;
  • 11111111d - > 1.1111111E7 - > 0:点右边的所有数字都具有重要性,将权力非规范化为10可获得更多信息,因此如果要保留此信息,则“无法”对数字进行标准化。这样(非规范化的数字),你在点的右边有0个数字。

修改

如评论所述,第一行是错误的,必须是1000000d -> 1000000.0 -> 1。原因是具有指数的数字具有与格式化数字不同的行为(当获得比例时)。

1的值是由于BigDecimal计算点右侧的数字(在本例中为1,单0),将数字减去drop(在这种情况下有一个,单0)并添加数学精度(默认为1) - >结果= 1。

答案 1 :(得分:1)

您正在查看报告的行为,因为您在提供的小数上调用了toString(),对于某些示例,这些示例以指数表示法表示,然后BigDecimal在选择时将其保留规模。

如果直接向BigDecimal构造函数提供double,则一直得到0。

new Double(1000000d).toString() //1.0E7

Double d = new Double(1000000d);
int scale = new BigDecimal(d).scale(); //0

Double d = new Double(10000000d);
int scale = new BigDecimal(d).scale(); //0

Double d = new Double(11111111d);
int scale = new BigDecimal(d).scale(); //0

<强>更新

scale本身并不是一个有用的属性。必须与unscaledValue一起考虑。所代表的数字是未缩放的值×10 ^ -scale。

即,

BigDecimal d = new BigDecimal(1000000d)
BigDecimal e = d.setScale(2)

int dScale = d.scale() //0
int dUnscaled = d.unscaledValue() //1000000

int eScale = e.scale() //2
int eUnscaled = e.unscaledValue() //100000000

de都代表1000000。但是,e保留有2个尾随零(小数点后的零)。

d.toString() //1000000
e.toString() //1000000.00