下一轮浮点舍入
Next round on floating-point rounding
这个问题与 this one 和许多其他问题有关,但不是重复的。我使用 double
s,说小数点后 6 位并使用
肯定是正确的
String.format("%f.6", x)
总是returns正确的值。然而,
String.valueOf(x)
没有。我需要 "round" 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
产生了可能的最佳结果,但它与我想要的相差 1ulp。
再说一遍:我不是在问如何舍入,我是在问如何更快地舍入。所以恐怕 BigDecimal
不是正确的选择。
问题是1e-6
不完全是10-6(实际上是0.000000999999999999999954748111825886258685613938723690807819366455078125)
而不是乘以这个,你应该除以 1e6
正好是 106,那么结果将是最接近 0.07 的浮点数(是 0.07
或 0.070000000000000006661338147750939242541790008544921875)。
这个问题与 this one 和许多其他问题有关,但不是重复的。我使用 double
s,说小数点后 6 位并使用
String.format("%f.6", x)
总是returns正确的值。然而,
String.valueOf(x)
没有。我需要 "round" 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
产生了可能的最佳结果,但它与我想要的相差 1ulp。
再说一遍:我不是在问如何舍入,我是在问如何更快地舍入。所以恐怕 BigDecimal
不是正确的选择。
问题是1e-6
不完全是10-6(实际上是0.000000999999999999999954748111825886258685613938723690807819366455078125)
而不是乘以这个,你应该除以 1e6
正好是 106,那么结果将是最接近 0.07 的浮点数(是 0.07
或 0.070000000000000006661338147750939242541790008544921875)。