这是怎么发生的?
这是直觉的行为,但我认为这是对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