admin管理员组

文章数量:1125088

I am using the pattern ###0.00% to format percentage values. From the documentation, it is mentioned that java.text.DecimalFormat uses HALF_EVEN rounding mode.

DecimalFormat df = new DecimalFormat("###0.00%");
List<Double> list = List.of(/*input list*/);
String result = list.stream().map(df::format).collect(Collectors.joining(", "));
System.out.print(result);

When I tried with the below input list:

0.012050, 0.012150, 0.012250, 0.012350, 0.012450, 0.012550, 0.012650, 0.012750, 0.012850, 0.012950

The output was:

1.21%, 1.21%, 1.23%, 1.23%, 1.24%, 1.26%, 1.26%, 1.27%, 1.29%, 1.29%

Whereas, when I tried with:

0.014050, 0.014150, 0.014250, 0.014350, 0.014450, 0.014550, 0.014650, 0.014750, 0.014850, 0.014950

I got as result as:

1.41%, 1.42%, 1.43%, 1.44%, 1.44%, 1.46%, 1.47%, 1.47%, 1.49%, 1.49%

It is evident that the way in which both the inputs were rounded are different.0.012350 gets rounded to 1.23% whereas 0.014350 becomes 1.44% When I debugged a bit through the formatting logic, I could see that during binary to ASCII conversion, some round off errors are being added resulting in the unexpected issues. example: for 0.012250, 0.0000000000001 are being added, causing it to be rounded to 1.23%.

Below is the code from java.text.DigitList from which the ASCII conversion is occuring:

FloatingDecimal.BinaryToASCIIConverter fdConverter  = FloatingDecimal.getBinaryToASCIIConverter(source);
boolean hasBeenRoundedUp = fdConverter.digitsRoundedUp();

And in some cases, the hasBeenRoundedUp comes as true, restricting any further rounding as part of the method.

Could anyone please help in understanding how exactly the formatting happens for the above mentioned decimal format.

本文标签: doubleDiscrepancy in javatextDecimalFormatformat using pattern quot000quotStack Overflow