這是怎麼發生的?
這是直覺的行爲,但我認爲這是對EL規範(LInk to oracle EL spec)爲師,即變量的脅迫爲BigDecimal的,正在做的方式。
代碼的第一行:
${(strutsForm.totalQuota div 1024 div 1024 div 1024)}
將迫使totalQuota 1024個價值爲BigDecimal,然後進行操作,並返回一個BigDecimal
第二行
${ ((strutsForm.currentUsage div 1024 div 1024) div (totalQuota)) * 100 }
將
首先將當前的使用強制爲Double,然後按1024 * 1024進行除法運算,返回Double。這將被強制爲BigDecimal(因爲總額是BigDecimal),然後執行A.divide(B, BigDecimal.ROUND_HALF_UP)
。這個輸出的前提取決於BigDecimal變量的大小(影響發生舍入的小數位數)。如果其中任何一個都是0級的,那麼這個舍入將產生一個整數結果,這就是你所看到的(然後乘以100)。
以下普通Java顯示了由步驟和結果上的步驟去
public class jsp_problem_steps
{
public static void main(String[] args)
{
Long currentUsage=209715200l; // 209715200l
BigDecimal totalQuota = new BigDecimal("343597383680"); // 343597383680
BigDecimal coerced = new BigDecimal("1024");
BigDecimal t = totalQuota.divide(coerced, BigDecimal.ROUND_HALF_UP).divide(coerced, BigDecimal.ROUND_HALF_UP).divide(coerced, BigDecimal.ROUND_HALF_UP);
System.out.println("coerced BigDecimal quota : " + t);
Double d = currentUsage.doubleValue()/1024d/1024d;
System.out.println("coerced Double usage : " + d);
BigDecimal coerced_d = (new BigDecimal(d));
System.out.println(coerced_d + " at scale " + coerced_d.scale());
BigDecimal res = coerced_d.divide(t,BigDecimal.ROUND_HALF_UP);
System.out.println("Result of division : " + res + " THIS IS UNEXPECTED!!!");
res = res.multiply(new BigDecimal("100"));
System.out.println("Final value : " + res);
}
}
給出輸出
coerced BigDecimal quota : 320
coerced Double usage : 200.0
200 at scale 0
Result of division : 1 THIS IS UNEXPECTED!!!
Final value : 100
問題的步驟是BigDecimal coerced_d = (new BigDecimal(d));
:的兩倍強制爲BigDecimal正在做使用一個BigDecimal構造函數給出一個具有比例尺0的BigDecimal。如果使用BigDecimal coerced_d = (new BigDecimal(d.toString()));
來完成構造,那麼您將得到您期望的值(即,作爲分割結果的6225和顯示的62.5)
這是有爭議的,這是否是預期的行爲或一個錯誤 - 從規範不清楚如何強制從一個Double到一個BigDecimal應該完成。
我怎樣才能得到正確的結果?
更改最後一行:
${ ((strutsForm.currentUsage div 1024 div 1024) div (totalQuota.doubleValue())) * 100 }
應該避免雙爲BigDecimal有問題的脅迫。我不能確定它會工作,因爲我沒有環境來測試,但似乎。
我認爲,最簡單的解決方案是在服務器端執行此計算並在視圖頁上使用結果。 – 2014-12-04 11:05:49
@SemihEker:你說得對。但是我正在尋找它是否可以在jsp上完成。 – 2014-12-04 12:06:57