BigDecimal(double)构造函数的不可预测性 [英] Unpredictability of the BigDecimal(double) constructor

查看:222
本文介绍了BigDecimal(double)构造函数的不可预测性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I started using Sonar recently in a project, and i got a PMD rule broken about using the constructor new BigDecimal(double val). When i read the java documentation, i found that new BigDecimal(double val) is somewhat unpredictable and that I should use new BigDecimal(String val) which is predictable.

以下是javadoc对 BigDecimal public BigDecimal(double val):

Here is what javadoc says for BigDecimal public BigDecimal(double val):


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

Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer.

注意:

这个构造函数的结果可能有些不可预测。一个
可能假设在Java中编写 new BigDecimal(0.1)会创建
BigDecimal 完全等于0.1(非标定值1,
,标度为1),但它实际上等于
0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能精确地表示为double(或者,对于那个
的问题,作为任何有限长度的二进制分数)。因此,传递给构造函数的值
并不完全等于
0.1,尽管有外观。

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

String构造函数,on另一方面,完全可以预测:
新的BigDecimal(0.1)创建一个 BigDecimal 正如人们所期望的那样,
正好等于0.1。因此,通常建议使用
,优先使用String构造函数,而不是

The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.

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

When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.

为什么这个构造函数确实存在? Isnt new BigDecimal(String val)足够吗?我什么时候应该使用 new BigDecimal(double val)构造函数?

Why does this constructor really exists? Isnt new BigDecimal(String val) enough for that matter? When should I use the new BigDecimal(double val) constructor?

推荐答案


为什么这个构造函数真的存在?

Why does this constructor really exists?

它转换 double 到BigDecimal。 BigDecimal的重点是提供尽可能多的精度,这就是这个构造函数的作用。

It converts the actual represented value of double to a BigDecimal. The whole point of BigDecimal is to give as much precision as possible and that is what this constructor does.

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

If you want to take the value you would get with a small amount of rounding the Double.toString(double) uses you can use

System.out.println(BigDecimal.valueOf(0.1));

打印

0.1




我应该何时使用新的BigDecimal(双val)构造函数

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

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

When you want to know the value double really represents. You can apply your own rounding as required.

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

When you use double you should always apply a sensible rounding. But, if you did that you may find you don't need BigDecimal. ;)

这篇关于BigDecimal(double)构造函数的不可预测性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆