我正在尝试理解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在数字很大时的行为。
提前致谢!
答案 0 :(得分:3)
您获得的比例是具有一定重要性的小数位数:
修改强>
如评论所述,第一行是错误的,必须是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
d
和e
都代表1000000
。但是,e
保留有2个尾随零(小数点后的零)。
d.toString() //1000000
e.toString() //1000000.00