Question

I'm trying to take two 7 digit numbers (source and target record counts) and calculate the percentage of missing records in the target count.

For example, my record counts could be 4084094 for the source, and 4081313 for the target. I'm also using the follow formula to calc the percentage: ((1 - (target / source)) * 100)

For my example, I should get the value of about .0681%

I'm am new to Java and JSP, and I'm not able to get the percentage to display correctly. I seem to only get a value rounded down to 0.

I've also tried BigDecimal, to no avail.

Even the following simple code displays the value of 1-1, so I obviously am doing somthing seriously wrong:

<%
BigDecimal percentMiss;
long tmp = 600/500;
percentMiss = BigDecimal.valueOf(tmp);
%>
<%=percentMiss.toString()%>-<%=tmp%>
Was it helpful?

Solution

The problem is in the following line

long tmp = 600/500;

You cannot store floating point numbers in a long, instead you should consider using the following code:

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

and then display tmp, which should have a value somewhere between 0 and 1 (in your case 1.2, because you have to change your calculation to 500 / 600)

OTHER TIPS

The problem is obviously that you are dividing two long numbers.

I would recommend using DecimalFormat to display the number. If you are using JSTL, then an even better solution is to use the format tags:

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

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

Your problem is that 600 and 500 are integer values, and a division between them will have an integer result, which you assign to a long integer. After this, the fractional part of the result is gone (twice) and you can't get it back.

In order to get a fractional result, at least one of the input values of the division needs to be non-integer. You can achieve this by casting them to double or float, or by making the literals explicitly double or float like this:

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

However, printing the result of a double/float divison will often have more decimal places than you want even if they shouldn't be in the result (e.g. 1/10 can result in 0.100000001490116119384765625), due to the way these numbers are stored as binary fractions.

You can eliminate these unwanted digits by using java.lang.DecimalFormat, but BigDecimal is a better option, since it internally uses decimal fractions and will therefore deliver the actually correct results while offering exact control over rounding modes. Of course, this requires you to use BigDecimal for the calculation itself, rather than as "voodoo ingredient" to fix an already broken result.

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

Read the API documentation for BigDecimal for more information.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top