The problem is indeed related to IEEE 754 number representation. Older JDKs like JDK 7 incorrectly implemented rounding double value representations close to ties (like 0.005).
As you can see none of them can be represented exactly.
The change affects > 4% of all rounding operations from n decimals to n-1 decimals with n > 1.
As far as I understand, the new behavior shall better align to the well-known problems with IEEE 754 (https://en.wikipedia.org/wiki/IEEE_floating_point) regarding number representation (eliminate some errorneous corner cases). This should be a minor change, but it isn't somehow (see below).
I ran the code given below with JDK 7 (1.7.0_10) and JDK 8 (1.8.0_65) on Mac OS.
It simply compares rounding 1 decimal first performed on a regular double and then on the corresponding BigDecimal. The default RoundingMode is HALF_EVEN.
Surprising to me is that compared to JDK 7 the number of cases where the rounding mechanism of JDK 8 deviates from the JDK 7 behavior is much higher than I expected.
EDIT: As requested here some example values JDK7 (1.7.0_10) vs. JDK8 (1.8.0_65) on Mac OS El Capitan 10.11.2.
For generating the small sample below I used a simpler generated source code, which can be found at the bottom of the table.
The sample only shows rounding from 3 to 2 decimals, but the phenomenon can be seen on any rounding from n to n-1 decimals with n > 1.
As you can see the values in the red columns are different compared to JDK7. This is what makes me nervous (round about 5%).
The BigDecimal columns are just for information. The difference between passing a double vs. passing a String to BigDecimal is plausible (precision loss).
NumberFormat nf = NumberFormat.getInstance(Locale.US);
assertEquals(RoundingMode.HALF_EVEN, nf.getRoundingMode());
nf.setGroupingUsed(false);
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
System.out.println("0.005;" + nf.format(0.005) + ";" + nf.format(Double.parseDouble("0.005")) + ";"
+ nf.format(new BigDecimal(0.005)) + ";" + nf.format(new BigDecimal("0.005")));
System.out.println("0.015;" + nf.format(0.015) + ";" + nf.format(Double.parseDouble("0.015")) + ";"
+ nf.format(new BigDecimal(0.015)) + ";" + nf.format(new BigDecimal("0.015")));
System.out.println("0.025;" + nf.format(0.025) + ";" + nf.format(Double.parseDouble("0.025")) + ";"
+ nf.format(new BigDecimal(0.025)) + ";" + nf.format(new BigDecimal("0.025")));
System.out.println("0.065;" + nf.format(0.065) + ";" + nf.format(Double.parseDouble("0.065")) + ";"
+ nf.format(new BigDecimal(0.065)) + ";" + nf.format(new BigDecimal("0.065")));
System.out.println("0.075;" + nf.format(0.075) + ";" + nf.format(Double.parseDouble("0.075")) + ";"
+ nf.format(new BigDecimal(0.075)) + ";" + nf.format(new BigDecimal("0.075")));
System.out.println("0.085;" + nf.format(0.085) + ";" + nf.format(Double.parseDouble("0.085")) + ";"
+ nf.format(new BigDecimal(0.085)) + ";" + nf.format(new BigDecimal("0.085")));
System.out.println("0.155;" + nf.format(0.155) + ";" + nf.format(Double.parseDouble("0.155")) + ";"
+ nf.format(new BigDecimal(0.155)) + ";" + nf.format(new BigDecimal("0.155")));
System.out.println("0.165;" + nf.format(0.165) + ";" + nf.format(Double.parseDouble("0.165")) + ";"
+ nf.format(new BigDecimal(0.165)) + ";" + nf.format(new BigDecimal("0.165")));
System.out.println("0.175;" + nf.format(0.175) + ";" + nf.format(Double.parseDouble("0.175")) + ";"
+ nf.format(new BigDecimal(0.175)) + ";" + nf.format(new BigDecimal("0.175")));
System.out.println("0.215;" + nf.format(0.215) + ";" + nf.format(Double.parseDouble("0.215")) + ";"
+ nf.format(new BigDecimal(0.215)) + ";" + nf.format(new BigDecimal("0.215")));
System.out.println("0.225;" + nf.format(0.225) + ";" + nf.format(Double.parseDouble("0.225")) + ";"
+ nf.format(new BigDecimal(0.225)) + ";" + nf.format(new BigDecimal("0.225")));
System.out.println("0.235;" + nf.format(0.235) + ";" + nf.format(Double.parseDouble("0.235")) + ";"
+ nf.format(new BigDecimal(0.235)) + ";" + nf.format(new BigDecimal("0.235")));
System.out.println("0.265;" + nf.format(0.265) + ";" + nf.format(Double.parseDouble("0.265")) + ";"
+ nf.format(new BigDecimal(0.265)) + ";" + nf.format(new BigDecimal("0.265")));
System.out.println("0.295;" + nf.format(0.295) + ";" + nf.format(Double.parseDouble("0.295")) + ";"
+ nf.format(new BigDecimal(0.295)) + ";" + nf.format(new BigDecimal("0.295")));
System.out.println("0.325;" + nf.format(0.325) + ";" + nf.format(Double.parseDouble("0.325")) + ";"
+ nf.format(new BigDecimal(0.325)) + ";" + nf.format(new BigDecimal("0.325")));
System.out.println("0.355;" + nf.format(0.355) + ";" + nf.format(Double.parseDouble("0.355")) + ";"
+ nf.format(new BigDecimal(0.355)) + ";" + nf.format(new BigDecimal("0.355")));
System.out.println("0.385;" + nf.format(0.385) + ";" + nf.format(Double.parseDouble("0.385")) + ";"
+ nf.format(new BigDecimal(0.385)) + ";" + nf.format(new BigDecimal("0.385")));
System.out.println("0.405;" + nf.format(0.405) + ";" + nf.format(Double.parseDouble("0.405")) + ";"
+ nf.format(new BigDecimal(0.405)) + ";" + nf.format(new BigDecimal("0.405")));
System.out.println("0.415;" + nf.format(0.415) + ";" + nf.format(Double.parseDouble("0.415")) + ";"
+ nf.format(new BigDecimal(0.415)) + ";" + nf.format(new BigDecimal("0.415")));
System.out.println("0.435;" + nf.format(0.435) + ";" + nf.format(Double.parseDouble("0.435")) + ";"
+ nf.format(new BigDecimal(0.435)) + ";" + nf.format(new BigDecimal("0.435")));
System.out.println("0.445;" + nf.format(0.445) + ";" + nf.format(Double.parseDouble("0.445")) + ";"
+ nf.format(new BigDecimal(0.445)) + ";" + nf.format(new BigDecimal("0.445")));
System.out.println("0.465;" + nf.format(0.465) + ";" + nf.format(Double.parseDouble("0.465")) + ";"
+ nf.format(new BigDecimal(0.465)) + ";" + nf.format(new BigDecimal("0.465")));
System.out.println("0.475;" + nf.format(0.475) + ";" + nf.format(Double.parseDouble("0.475")) + ";"
+ nf.format(new BigDecimal(0.475)) + ";" + nf.format(new BigDecimal("0.475")));
System.out.println("0.495;" + nf.format(0.495) + ";" + nf.format(Double.parseDouble("0.495")) + ";"
+ nf.format(new BigDecimal(0.495)) + ";" + nf.format(new BigDecimal("0.495")));
System.out.println("0.505;" + nf.format(0.505) + ";" + nf.format(Double.parseDouble("0.505")) + ";"
+ nf.format(new BigDecimal(0.505)) + ";" + nf.format(new BigDecimal("0.505")));
System.out.println("0.525;" + nf.format(0.525) + ";" + nf.format(Double.parseDouble("0.525")) + ";"
+ nf.format(new BigDecimal(0.525)) + ";" + nf.format(new BigDecimal("0.525")));
System.out.println("0.545;" + nf.format(0.545) + ";" + nf.format(Double.parseDouble("0.545")) + ";"
+ nf.format(new BigDecimal(0.545)) + ";" + nf.format(new BigDecimal("0.545")));
System.out.println("0.575;" + nf.format(0.575) + ";" + nf.format(Double.parseDouble("0.575")) + ";"
+ nf.format(new BigDecimal(0.575)) + ";" + nf.format(new BigDecimal("0.575")));
System.out.println("0.595;" + nf.format(0.595) + ";" + nf.format(Double.parseDouble("0.595")) + ";"
+ nf.format(new BigDecimal(0.595)) + ";" + nf.format(new BigDecimal("0.595")));
System.out.println("0.615;" + nf.format(0.615) + ";" + nf.format(Double.parseDouble("0.615")) + ";"
+ nf.format(new BigDecimal(0.615)) + ";" + nf.format(new BigDecimal("0.615")));
System.out.println("0.645;" + nf.format(0.645) + ";" + nf.format(Double.parseDouble("0.645")) + ";"
+ nf.format(new BigDecimal(0.645)) + ";" + nf.format(new BigDecimal("0.645")));
System.out.println("0.665;" + nf.format(0.665) + ";" + nf.format(Double.parseDouble("0.665")) + ";"
+ nf.format(new BigDecimal(0.665)) + ";" + nf.format(new BigDecimal("0.665")));
System.out.println("0.685;" + nf.format(0.685) + ";" + nf.format(Double.parseDouble("0.685")) + ";"
+ nf.format(new BigDecimal(0.685)) + ";" + nf.format(new BigDecimal("0.685")));
System.out.println("0.695;" + nf.format(0.695) + ";" + nf.format(Double.parseDouble("0.695")) + ";"
+ nf.format(new BigDecimal(0.695)) + ";" + nf.format(new BigDecimal("0.695")));
System.out.println("0.715;" + nf.format(0.715) + ";" + nf.format(Double.parseDouble("0.715")) + ";"
+ nf.format(new BigDecimal(0.715)) + ";" + nf.format(new BigDecimal("0.715")));
System.out.println("0.735;" + nf.format(0.735) + ";" + nf.format(Double.parseDouble("0.735")) + ";"
+ nf.format(new BigDecimal(0.735)) + ";" + nf.format(new BigDecimal("0.735")));
System.out.println("0.765;" + nf.format(0.765) + ";" + nf.format(Double.parseDouble("0.765")) + ";"
+ nf.format(new BigDecimal(0.765)) + ";" + nf.format(new BigDecimal("0.765")));
System.out.println("0.785;" + nf.format(0.785) + ";" + nf.format(Double.parseDouble("0.785")) + ";"
+ nf.format(new BigDecimal(0.785)) + ";" + nf.format(new BigDecimal("0.785")));
System.out.println("0.805;" + nf.format(0.805) + ";" + nf.format(Double.parseDouble("0.805")) + ";"
+ nf.format(new BigDecimal(0.805)) + ";" + nf.format(new BigDecimal("0.805")));
System.out.println("0.815;" + nf.format(0.815) + ";" + nf.format(Double.parseDouble("0.815")) + ";"
+ nf.format(new BigDecimal(0.815)) + ";" + nf.format(new BigDecimal("0.815")));
System.out.println("0.835;" + nf.format(0.835) + ";" + nf.format(Double.parseDouble("0.835")) + ";"
+ nf.format(new BigDecimal(0.835)) + ";" + nf.format(new BigDecimal("0.835")));
System.out.println("0.855;" + nf.format(0.855) + ";" + nf.format(Double.parseDouble("0.855")) + ";"
+ nf.format(new BigDecimal(0.855)) + ";" + nf.format(new BigDecimal("0.855")));
System.out.println("0.885;" + nf.format(0.885) + ";" + nf.format(Double.parseDouble("0.885")) + ";"
+ nf.format(new BigDecimal(0.885)) + ";" + nf.format(new BigDecimal("0.885")));
System.out.println("0.905;" + nf.format(0.905) + ";" + nf.format(Double.parseDouble("0.905")) + ";"
+ nf.format(new BigDecimal(0.905)) + ";" + nf.format(new BigDecimal("0.905")));
System.out.println("0.925;" + nf.format(0.925) + ";" + nf.format(Double.parseDouble("0.925")) + ";"
+ nf.format(new BigDecimal(0.925)) + ";" + nf.format(new BigDecimal("0.925")));
System.out.println("0.955;" + nf.format(0.955) + ";" + nf.format(Double.parseDouble("0.955")) + ";"
+ nf.format(new BigDecimal(0.955)) + ";" + nf.format(new BigDecimal("0.955")));
System.out.println("0.975;" + nf.format(0.975) + ";" + nf.format(Double.parseDouble("0.975")) + ";"
+ nf.format(new BigDecimal(0.975)) + ";" + nf.format(new BigDecimal("0.975")));
System.out.println("0.995;" + nf.format(0.995) + ";" + nf.format(Double.parseDouble("0.995")) + ";"
+ nf.format(new BigDecimal(0.995)) + ";" + nf.format(new BigDecimal("0.995")));
System.out.println("1.015;" + nf.format(1.015) + ";" + nf.format(Double.parseDouble("1.015")) + ";"
+ nf.format(new BigDecimal(1.015)) + ";" + nf.format(new BigDecimal("1.015")));