2012-01-06 53 views
15

La siguiente no siempre se comportan como era de esperar:Comprobando si un valor BigDecimal es cero en una expresión JSP EL

<c:if test="${someBigDecimal == 0}"> 

Si someBigDecimal tiene un valor de 0, pero tiene una escala diferente de 0, la == operación devuelve falso. Es decir, devuelve verdadero cuando someBigDecimal es un nuevo BigDecimal ("0"), pero falso cuando someBigDecimal es un nuevo BigDecimal ("0.00").

Esto resulta de la JSP 2.0, 2.1, y 2.2 especificaciones, que estado:

Para <,>, < =,> =:

Si A o B es BigDecimal, coaccionar tanto A y B a BigDecimal y usan el valor de retorno de A.compareTo (B).

Para ==, =:

Si A o B es BigDecimal, coaccionar tanto A como B a BigDecimal y luego:

  • Si el operador == es, devolver una .equals (B)
  • Si el operador es! =, volver! A.equals (B)

Esto significa que los operadores == y != dan como resultado una llamada al método .equals(), que compara no solo los valores, sino también la escala de los BigDecimals. Los otros operadores de comparación dan como resultado una llamada al método .compareTo(), que compara solo los valores.

Por supuesto, la siguiente funcionaría:

<c:if test="${not ((someBigDecimal < 0) or (someBigDecimal > 0))}"> 

Pero esto es más bien feo, hay una mejor manera de hacer esto?

+3

¿Cuál es tu pregunta? – kcdragon

+0

@ user617090 Solo me pregunto cuál es la mejor manera de lidiar con esto. He editado la pregunta para aclarar esto. –

+0

¿Qué sucede si usas '== 0.0'? –

Respuesta

10

En JSP 2.2 EL y por encima de esta expresión se evaluará como true:

${someBigDecimal.unscaledValue() == 0} 

Esto evitará cualquier pérdida de precisión, pero supone que someBigDecimal es siempre del tipo BigDecimal.

Un custom EL function es probablemente el mejor enfoque para versiones anteriores de EL:

${fn:isZero(someBigDecimal)} 

El núcleo del problema es que este código Java evalúa a false porque ZERO tiene un scale de 0 y la nuevo BigDecimal tiene una escala distinta de cero:

BigDecimal.ZERO.setScale(3).equals(BigDecimal.ZERO) 
+0

Gracias por su respuesta. Estamos estancados con JSP 2.1 por ahora. Habíamos pensado en una función personalizada, pero esperaba evitarla. Ahora estoy de acuerdo, sin embargo, que es el mejor enfoque. –

2

Con la última versión de EL (apoyado por Tomcat 7, por ejemplo), puede intentar:

<c:if test="${someBigDecimal.doubleValue() == 0}"> 
2
<c:if test="${someBigDecimal.compareTo(BigDecimal.ZERO) == 0}"> 
+0

Creo que este sería el camino a seguir si estuviéramos en la especificación JSP 2.2. Mi pregunta se limitó a comparar un BigDecimal contra un cero literal, pero esto también funcionaría para comparar dos valores de BigDecimal. –

2
<c:if test="${someBigDecimal eq 0}"> 
+1

¿Estás diciendo que 'eq' se comporta de forma diferente a' == '? Porque entiendo que 'eq' es solo un alias para' == '. –

+0

Sí, son diferentes. Al igual que la relación entre 'igual()' y '==' en java. – peakmuma

+1

Lo sentimos, pero 'eq' es solo un alias para' == '; [no son diferentes] (http://stackoverflow.com/questions/2087721/difference-between-eq-and-in-jsp). –

0

Usted puede intentar función signo:

<c:if test="#{someBigDecimal.signum() == 0}"> 
Cuestiones relacionadas