First of, your final value is a Double
it does not have 2 digits! When you do Double.valueOf it will become the closest representable value. If you actually want two digits in Java then you need to use BigDecimal which actually stores base 10 floating point representations.
The trick is, the value you are using is not what you think it is.
double d = 17.755;
Java doubles are power of 2 exponent, so a number that appears to be an exact value in decimal, has a repeating representation in float. That means it needs to be truncated and the closest value is used.
jshell> double d = 17.755;
d ==> 17.755
jshell> var x = new BigDecimal(d);
x ==> 17.754999999999999005240169935859739780426025390625
jshell> var y = new BigDecimal("17.755");
y ==> 17.755
Now you can see that x
which is an exact representation of d
is actually less than 17.755
so when you round it it goes down.
y
on the other hand is exactly 17.755 and will round according the the rules you apply.
jshell> System.out.printf("%.2f\n", y);
17.76
jshell> System.out.printf("%.2f\n", x);
17.75