This question is related to this one and many others, but not a duplicate. I work with double
s, 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.