2

No se como podría redondear y mostrar en dos decimales. Aunque he utilizado para el redondeo la clase Math.round pero no he podido solucionar esto. introducir la descripción de la imagen aquí

Les dejo el código

Bean:

private double igv;
private double subtotal;    

public void agregar() {
    subtotal+=Math.round((det1.getCantidad()*det1.getPreciocompra()/1.18)*100.0)/100.0;
            igv+=Math.round(((det1.getCantidad()*det1.getPreciocompra()/1.18)*0.18)*100.0)/100.0;
}

Facelets:

<p:columnGroup type="footer">                              
<p:row>                              
  <p:column colspan="4" style="text-align:right" footerText="SUB-TOTAL" />
  <p:column footerText="#{entradaBean.subtotal}" style="text-align: right"   />                           
</p:row>  
 <p:row>                              
  <p:column colspan="4" style="text-align:right" footerText="IGV:" />
  <p:column footerText="#{entradaBean.igv}" style="text-align: right" />                           
   </p:row>                              
 <p:row>                              
  <p:column colspan="4" style="text-align:right" footerText="Monto Total:" />
  <p:column footerText="S/.#{entradaBean.montototal}" style="text-align: right" />
  </p:row>
</p:columnGroup>
Libra2880
  • 447
  • 8
  • 20

4 Answers4

5

Primero que nada, no utilices double, es mejor utilizar BigDecimal puesto que ofrece mejor precisión al trabajar con estos números. Sobretodo, deberías utilizar BigDecimal al trabajar en operaciones financieras como la que muestras en tu ejemplo.

De todas maneras, si es que no vas a cambiar el tipo de dato de tus variables, lo que debes hacer es utilizar <f:convertNumber>. Esta etiqueta te permite dar el formato al número como cantidad de posiciones decimales, moneda, y otros. Aquí te dejo un ejemplo:

<h:outputText value="#{bean.subtotal}">
    <f:convertNumber pattern="#0.00" />
</h:outputText>

El campo pattern se basa en los patrones que soporta la clase DecimalFormat. Para comprender el patrón de arriba, se deben entender los siguientes símbolos:

  • #: cualquier dígito, opcional.
  • .: punto decimal.
  • 0: cualquier dígito, obligatorio.

El patrón utilizado #0.00 significa que el número puede tener uno o más digitos en la parte entera, luego el punto decimal y por último dos números decimales de manera obligatoria.

Basado en tu código Facelets, deberías cambiarlo de esta manera:

<p:row>
    <p:column colspan="4" style="text-align:right"
        footerText="SUB-TOTAL" />
    <p:column style="text-align: right">
         <f:facet name="footer">
             <h:outputText value="#{entradaBean.subtotal}">
                <f:convertNumber pattern="#0.00" />
            </h:outputText>
         </f:facet>
    </p:column>
    <!-- lo mismo para los otros campos -->
</p:row>
  • me genera este error voy a investigarlo Parent not an instance of ValueHolder: org.primefaces.component.column – Libra2880 Mar 07 '16 at 16:47
  • edite mi pregunta y puse el código no se porque no muestra ??? – Libra2880 Mar 07 '16 at 16:49
  • Eso es porque no está indentado como código que reconocería Markdown, y por defecto evita el renderizado de cualquier código con estructura HTML para evitar problemas de inyección. Acabo de editar el texto para que se pueda ver el código. –  Mar 07 '16 at 16:50
  • ok gracias Luiggi – Libra2880 Mar 07 '16 at 16:52
  • Respuesta actualizada. Por favor revísalo y dime si aún hay problemas. –  Mar 07 '16 at 16:58
  • no muestra el resultado del subtotal y si añado me genera el mismo error Parent not an instance of ValueHolder: org.primefaces.component.column – Libra2880 Mar 07 '16 at 17:39
  • Disculpa, hubo un error en el código publicado. Ya lo corregí. Esto debería solucionar el problema. –  Mar 07 '16 at 17:42
  • si esta pero el problema esta en la precisión del subtotal conforme va aumentando se va perdiendo la precisión del resultado en el subtotal – Libra2880 Mar 07 '16 at 18:08
  • Para obtener una mejor precisión utiliza `BigDecimal`, no `double`. Un concepto general de trabajar con `double` (y lo mismo sucede con `float`) es que no es preciso en operaciones decimales. Hay más detalle al respecto [aquí](http://es.stackoverflow.com/q/197/227). –  Mar 07 '16 at 18:11
1

Nunca pero nunca utilices el formato Double cuando hagas cuentas financieras, los montos no cuadrarán pues Java en ese caso prioriza eficiencia sobre precisión. Utiliza BigDecimal

 BigDecimal valor = new BigDecimal(37.288136);

 BigDecimal valorRedondeado = valor.setScale(2, BigDecimal.ROUND_HALF_UP)

Donde:

  • ROUND_HALF_UP indica que se redondee si es igual o mayor a 5 en el último dígito de la parte decimal luego redondeable.
  • 2 es el número de decimales que deseas.

Por lo que el resultado sería de 37.29

Espero te sirva y aceptes mi respuesta.

Deoxyseia
  • 474
  • 3
  • 12
0

Si se esta usando primefaces, se podia usar primefaces extensions http://www.primefaces.org/showcase-ext/sections/inputNumber/basicUsage.jsf

Lcop
  • 724
  • 3
  • 11
0

Puedes cambiar la , por . o darle mas decimales si quieres , funciona muy parecido a los format que uno realiza con datos tipo Date

 private static DecimalFormat df2 = new DecimalFormat(",##");

        public static void main(String[] args) {

            double input = 32.123456;
            System.out.println("double : " + input);
            System.out.println("double : " + df2.format(input));

        }
Daniel ORTIZ
  • 469
  • 3
  • 15