Pregunta

Estoy intentando tomar dos números de 7 dígitos (conteos de registros de origen y destino) y calcular el porcentaje de registros faltantes en el conteo objetivo.

Por ejemplo, mis recuentos de registros podrían ser 4084094 para la fuente y 4081313 para el objetivo. También estoy usando la siguiente fórmula para calcular el porcentaje: ((1 - (destino / fuente)) * 100)

Para mi ejemplo, debería obtener el valor de aproximadamente .0681%

Soy nuevo en Java y JSP, y no puedo obtener el porcentaje para mostrarlo correctamente. Parece que solo obtengo un valor redondeado a 0.

También he intentado BigDecimal, en vano.

Incluso el siguiente código simple muestra el valor de 1-1, así que obviamente estoy haciendo algo muy mal:

<%
BigDecimal percentMiss;
long tmp = 600/500;
percentMiss = BigDecimal.valueOf(tmp);
%>
<%=percentMiss.toString()%>-<%=tmp%>
¿Fue útil?

Solución

El problema está en la siguiente línea

long tmp = 600/500;

No puede almacenar números de punto flotante por mucho tiempo, en vez de eso, debería considerar usar el siguiente código:

double tmp = (double)600 / (double)500;

y luego muestre tmp, que debería tener un valor entre 0 y 1 (en su caso 1.2, porque tiene que cambiar su cálculo a 500/600)

Otros consejos

El problema es obviamente que estás dividiendo dos números largos.

Recomendaría utilizar DecimalFormat para mostrar el número. Si está utilizando JSTL, una solución aún mejor es utilizar etiquetas de formato :

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<fmt:formatNumber value="${value}" minFractionDigits="2" maxFractionDigits="2"/>

Su problema es que 600 y 500 son valores enteros, y una división entre ellos tendrá un resultado entero, que asignará a un entero largo. Después de esto, la parte fraccionaria del resultado desaparece (dos veces) y no se puede recuperar.

Para obtener un resultado fraccionario, al menos uno de los valores de entrada de la división debe ser no entero. Puedes lograrlo lanzándolos a double o float , o haciendo que los literales se doblen o floten explícitamente de esta manera:

500.0 // implicitly double
500f // float literal
500d // double literal

Sin embargo, la impresión del resultado de una división doble / flotante a menudo tendrá más decimales de los que desea, incluso si no deberían estar en el resultado (por ejemplo, 1/10 puede dar como resultado 0.100000001490116119384765625 ), debido a la forma en que estos números se almacenan como fracciones binarias .

Puede eliminar estos dígitos no deseados utilizando java.lang.DecimalFormat , pero BigDecimal es una mejor opción, ya que utiliza fracciones decimales internamente y, por lo tanto, entregará el código real. Resultados correctos mientras se ofrece un control exacto sobre los modos de redondeo. Por supuesto, esto requiere que uses BigDecimal para el cálculo en sí mismo, en lugar de usar " voodoo ingrediente " para arreglar un resultado ya roto.

new BigDecimal(600).divide(new BigDecimal(500))

Lea la documentación de la API para BigDecimal para más información.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top