BigDecimal(double)构造函数的不可预测性

gdf*_*osa 14 java

我最近在一个项目中开始使用Sonar,并且我得到了关于使用构造函数的PMD规则new BigDecimal(double val).当我阅读java文档时,我发现新的BigDecimal(double val)有些不可预测,我应该使用new BigDecimal(String val)哪个是可预测的.

这是javadoc所说的BigDecimal public BigDecimal(double val):

将double转换为BigDecimal,它是double的二进制浮点值的精确十进制表示形式.返回的BigDecimal的比例是最小值,使得(10scale×val)是整数.

笔记:

这个构造函数的结果可能有点不可预测.有人可能会认为new BigDecimal(0.1)用Java 编写创建的数字 BigDecimal恰好等于0.1(未缩放值为1,等级为1),但它实际上等于0.1000000000000000055511151231257827021181583404541015625.这是因为0.1不能精确地表示为double(或者,就此而言,作为任何有限长度的二进制分数).因此,传递给构造函数的值并不完全等于0.1,尽管有外观.

另一方面,String构造函数是完全可预测的:正如人们所期望的那样,write new BigDecimal("0.1")会创建一个BigDecimal与0.1完全相等的值.因此,通常建议优先使用String构造函数.

当必须将double用作a的源时BigDecimal,请注意此构造函数提供了精确的转换; 它不会产生与使用该Double.toString(double)方法将double转换为String 然后使用 BigDecimal(String)构造函数相同的结果 .要获得该结果,请使用静态 valueOf(double)方法.

为什么这个构造函数确实存在?心不是new BigDecimal(String val)能有这样的事?我new BigDecimal(double val)什么时候应该使用构造函数?

Pet*_*rey 8

为什么这个构造函数确实存在?

它将实际表示的值转换double为BigDecimal.BigDecimal的重点是提供尽可能多的精度,这就是这个构造函数的作用.

如果你想通过少量四舍五入来获得Double.toString(double)你可以使用的价值

System.out.println(BigDecimal.valueOf(0.1));
Run Code Online (Sandbox Code Playgroud)

版画

0.1
Run Code Online (Sandbox Code Playgroud)

我什么时候应该使用新的BigDecimal(double val)构造函数

当你想知道double真正代表的价值时.您可以根据需要应用自己的舍入.

当你使用时,double你应该总是应用合理的四舍五入.但是,如果你这样做,你可能会发现你不需要BigDecimal.;)


dan*_*uch 5

When should I use the new BigDecimal(double val) constructor?

最好 - 无处。

如果您愿意使用 BigDecimals,那么使用 double 的构造函数意味着失去精确数字表示的所有好处。

Why does this constructor really exists?

因为有时您只有 double,您想要转换为 BigDecimal。强迫你在.toString()两者之间使用只是愚蠢的;)