問題:JSFを介してBigDecimalをフォーマットする必要がありますが、JSFはBigDecimalの精度を破壊しています。
JSF:
<h:outputText value="#{webUtilMB.roundUp(indexPrice.percentage, 2)}"/>
Java:
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を取得するために値に対して「newBigDecimal(double)」を呼び出すよりも、DoubleではなくStringに変換するBigDecimal値を取得していたようです-これは間違った値を返します。
修正:これを解決する1つの方法は、次のコードを使用することです。
@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);
}
}
しかし、それは私にはハックのように思えます。
これを修正するためのアイデアとその背後にある理由。ありがとう。