[英]Next round on floating-point rounding
这个问题与这个和其他许多问题有关,但不是重复的。 我使用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
产生了最好的结果,但距离我想要的只有一个ulp。
再一次:我不是在问如何绕圈,我问的是怎么做得更快。 所以我担心, BigDecimal
不是要走的路。
问题是1e-6
不完全是10 -6 (实际上是0.000000999999999999999954748111825886258685613938723690807819366455078125)
不应乘以此值,而应除以1e6
(正好是10 6) ,然后结果将是最接近0.07的浮点数(即0.07
或0.070000000000000006661338147750939242541790008544921875)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.