Reputation: 33
I am creating an app to calculate a mark average with percents, but the problem is that BigDecimal not always rounding the average, for example if the mark average is 3.85 BigDecimal ROUND_HALF_UP in scale 1 should round to 3.9 but it show the average like 3.8, that happened with only some specific times, sometimes BigDecimal round 4.95 like 5.0 and its good, but I don't know why happened and where is the problem. This is an example code for you can see the problem:
import java.io.*;
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) throws IOException{
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader buff = new BufferedReader (input);
//temporal
float average=0;
float mark1=0;
float mark2=0;
float percent1=0.75f;
float percent2=0.25f;
for(int i=0;i<1;i++){
System.out.println("Enter mark 1 (75%) : ");
mark1=Float.parseFloat(buff.readLine());
}
for(int i=0;i<1;i++){
System.out.println("Enter mark 2 (25%): ");
mark2=Float.parseFloat(buff.readLine());
}
average= ((mark1*percent1)+(mark2*percent2));
// convert to BigDecimal
BigDecimal bd = new BigDecimal(average);
BigDecimal roundingMark = bd.setScale(1,
BigDecimal.ROUND_HALF_UP);
System.out.println(" the complete average is :"+average);
System.out.println(" The rounding average is :"+roundingMark);
}
}
You should put in the first mark 4.5 and in the second mark 1.9 the result will be 3.8 and should be 3.9
Please excuse my for bad English and thank so much for read :)
Upvotes: 0
Views: 1500
Reputation: 7241
You should use BigDecimal
for calculations, not just for rounding.
Meaning, mark1
, mark2
, percent1
, percent2
and average
should be BigDecimal
s. The issue you are facing here is a precision problem: float
s are not precise enough to guarantee exactness of computation, so what you think should be 3.85
actually is 3.849999999999
. Try to print bd
and you will its original value to be 849999904632568359375
(at least this is the exact value for me).
EDIT, expansion: it just occurred to me you may also misunderstanding the meaning of ROUND_HALF_UP. I cite from the documentation
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up. Behaves as for ROUND_UP if the discarded fraction is ≥ 0.5; otherwise, behaves as for ROUND_DOWN. Note that this is the rounding mode that most of us were taught in grade school.
So, summing the precision issue, causing the real value of bd
to be closer to 3.8
than to 3.9
, and the intended behavior of ROUND_HALF_UP
, you should have now a complete explanation of your results.
Upvotes: 2