提问人:jeninja 提问时间:11/12/2021 最后编辑:jeninja 更新时间:11/14/2021 访问量:755
BigDecimal 在与浮点数转换时不保留舍入值 [duplicate]
BigDecimal not retaining rounded value when converting to/from float [duplicate]
问:
我有一个函数,可以使用BigDecimal.setScale将浮点数四舍五入到n位数
private float roundPrice(float price, int numDigits) {
BigDecimal bd = BigDecimal.valueOf(price);
bd = bd.setScale(numDigits, RoundingMode.HALF_UP);
float roundedFloat = bd.floatValue();
return roundedFloat;
}
public void testRoundPrice() {
float numberToRound = 0.2658f;
System.out.println(numberToRound);
float roundedNumber = roundPrice(numberToRound, 5);
System.out.println(roundedNumber);
BigDecimal bd = BigDecimal.valueOf(roundedNumber);
System.out.println(bd);
}
输出:
0.2658
0.2658
0.26579999923706055
如何防止 BigDecimal 在四舍五入值的末尾添加所有这些额外的数字?
注意:我无法执行以下操作,因为我无法访问 api 调用函数中的位数。
System.out.println(bd.setScale(5, RoundingMode.CEILING));
答:
反之亦然。 说的是实话。0.26579999923706055 更接近您在四舍五入之前和之后一直得到的值。A 是二进制而不是十进制数,不能精确地保持 0.2658。实际上,0.265799999237060546875 是我们所能得到的。BigDecimal
float
float
打印浮点数时,不会获得完整值。会发生一些舍入,因此尽管具有上述值,但您只能看到 .float
0.2658
当你从 创建 时,你实际上是首先转换为 a(因为这是接受的)。的值与 相同,但打印为 0.26579999923706055,这也是您获得的值。BigDecimal
float
double
BigDecimal.valueOf()
double
float
BigDecimal
如果您想要一个打印值而不是其中的确切值或接近的东西,以下方法可能会起作用:BigDecimal
float
BigDecimal bd = new BigDecimal(String.valueOf(roundedNumber));
System.out.println(bd);
输出:
0.2658
但是,您可能会对其他值感到惊讶,因为 a 没有那么高的精度。float
编辑:您有效地将float
->double
-> String
-> BigDecimal
转换。
达伍德·伊本·卡里姆(Dawood ibn Kareem)的这些有见地的评论让我进行了一些研究:
实际上是0.265799999237060546875。
嗯,是通过调用值返回的值。这与数字不同 其实由那来代表.这就是为什么通常不返回相同值的原因 如。了解 如果您要使用浮点值,则有所不同 和 .
0.26579999923706055
toString
double
double
BigDecimal.valueOf(double)
new BigDecimal(double)
BigDecimal
那么到底发生了什么:
- 在四舍五入之前和之后,您的内部值为 0.265799999237060546875。
float
- 当您将 传递给 时,您实际上是在将 -> -> -> 转换。
float
BigDecimal.valueOf(double)
float
double
String
BigDecimal
- 的值与 0.265799999237060546875 相同。
double
float
- 将 的转换四舍五入 一点 .
String
"0.26579999923706055"
- 因此,你得到的值是 0.26579999923706055,即你看到和询问的值。
BigDecimal
- 的值与 0.265799999237060546875 相同。
从以下文档:BigDecimal.valueOf(double)
使用 's 将 a 转换为 a 方法提供的规范字符串表示形式。
double
BigDecimal
double
Double.toString(double)
链接
- Stack Overflow 问题:浮点数学是否损坏?
- 文档:
BigDecimal.valueOf(double)
- Stack Overflow 问题:BigDecimal - 使用 new 或 valueOf
评论
0.26579999923706055
toString
double
double
BigDecimal.valueOf(double)
new BigDecimal(double)
BigDecimal
我决定修改我的程序,以使用 BigDecimal 作为对象中财产价格的基本类型,而不是类型 float。虽然一开始很棘手,但从长远来看,它绝对是更清洁的解决方案。
public class Order {
// float price; // old type
BigDecimal price; // new type
}
评论
BigDecimal
。new BigDecimal("0.2658")