问题:需要通过 JSF 格式化 BigDecimal,但是 JSF 破坏了 BigDecimal 的精度。
JSF:
<h:outputText value="#{webUtilMB.roundUp(indexPrice.percentage, 2)}"/>
爪哇:
public class IndexPrice {
public BigDecimal getPercentage(){ return new BigDecimal("1.325"); }
}
@ManagedBean("webUtilMb")
public class WebUtilManagedBean{
public BigDecimal roundUp(BigDecimal dbvalue, int scale){
return dbvalue.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP);
}
}
在 WebUtilManagedBean.roundUp 方法中有一个断点显示“dbvalue”是“1.3249999999999999555910790149937383830547332763671875”而不是“1.325”。
然后我重载了 WebUtilManagedBean 中的 roundUp 方法:
public Double roundUp(Double dvalue, int scale){
System.out.println(dvalue);
}
在这个重载方法中有一个断点时让我感到惊讶的是: - 'dvalue' 是 '1.325',这是正确的。- 该方法实际上被调用而不是 roundUp(BigDecimal, int) 方法。
后来我尝试了 BigDecimal 构造函数,结果如下:
BigDecimal db1 = new BigDecimal("1.325"); -> 1.325
BigDecimal db2 = new BigDecimal(1.325d); -> 1.3249999999999999555910790149937383830547332763671875
理论:从上面看,似乎 JSF 将我的 BigDecimal 值转换为 String,而不是 Double,而不是在值上调用“new BigDecimal(double)”来获取 BigDecimal - 它返回错误的值。
修复:解决此问题的一种方法是使用以下代码:
@ManagedBean("webUtilMb")
public class WebUtilManagedBean{
public Double roundUp(Double dvalue, int scale){
return this.roundUp(**new BigDecimal(dvalue.toString())**, BigDecimal.ROUND_HALF_UP);
}
public BigDecimal roundUp(BigDecimal dbvalue, int scale){
return dbvalue.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP);
}
}
但这对我来说似乎是一种黑客行为。
有关解决此问题的任何想法及其背后的原因。谢谢。