This question is related to this one and many others, but not a duplicate. I work with doubles, which are surely correct to say 6 decimal places and using
String.format("%f.6", x)
always returns the correct value. However,
String.valueOf(x)
does not. I'd need to "round" x, so that it'd produce the same (or shorter in case of trailing zeros) result as formatting to 6 decimal places. I don't want the exact representation of the decimal number and I know it does not exist. Using
x = Double.parseDouble(String.format("%.6f", x))
gives me what I want, but I'm looking for some more straightforward method (faster and producing no garbage). The obvious way for rounding
x = 1e-6 * Math.round(1e6 * x)
does not work.
As an example consider the following snipped
double wanted = 0.07;
double given = 0.07000000455421122;
double wrong = 1e-6 * Math.round(1e6 * given);
double slow = Double.parseDouble(String.format("%.6f", given));
double diff = wrong - wanted;
double ulp = Math.ulp(wrong);
computing these values
wanted 0.07
given 0.07000000455421122
wrong 0.06999999999999999
slow 0.07
diff -1.3877787807814457E-17
ulp 1.3877787807814457E-17
The problem seems to be that 1e-6 * 70000 produces the best possible result, but it's one ulp away from what I want.
Once again: I'm not asking how to round, I'm asking how to do it faster. So I'm afraid, BigDecimal is not the way to go.
 
     
    