此问题与this one和其他许多问题有关,但不是重复。我使用double
s,这肯定是正确的说小数点后6位并使用
String.format("%f.6", x)
始终返回正确的值。然而,
String.valueOf(x)
没有。我需要“舍入”x
,以便它生成相同的(或者在尾随零的情况下更短)结果为格式化为6位小数。 我不想要十进制数的确切表示,我知道它不存在。使用
x = Double.parseDouble(String.format("%.6f", x))
给了我想要的东西,但我正在寻找一些更直接的方法(更快,不产生垃圾)。四舍五入的明显方法
x = 1e-6 * Math.round(1e6 * x)
不工作。
作为示例,请考虑以下剪切
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);
计算这些值
wanted 0.07
given 0.07000000455421122
wrong 0.06999999999999999
slow 0.07
diff -1.3877787807814457E-17
ulp 1.3877787807814457E-17
问题似乎是1e-6 * 70000
产生了最好的结果,但距离我想要的距离只有一个。
再一次:我不是要问如何回合,我问的是如何更快地做到这一点。所以我担心,BigDecimal
不是可行的方式。
答案 0 :(得分:3)
问题是1e-6
不完全是10 -6 (实际上是0.000000999999999999999954748111825886258685613938723690807819366455078125)
除了乘以这个,你应该除以1e6
,恰好是10 6 ,然后结果将是最接近0.07的浮点数({{1} }或0.070000000000000006661338147750939242541790008544921875)。