Java 下一轮浮点舍入
这个问题与其他许多问题有关,但不是重复的。我使用的是Java 下一轮浮点舍入,java,floating-point,decimal,rounding,Java,Floating Point,Decimal,Rounding,这个问题与其他许多问题有关,但不是重复的。我使用的是doubles,它的小数点后6位和 String.format("%f.6", x) 始终返回正确的值。但是, String.valueOf(x) 没有。我需要“舍入”x,这样它将产生与格式设置相同的结果(或在尾随零的情况下更短),精确到小数点后6位我不想要十进制数的精确表示,我知道它不存在。使用 x = Double.parseDouble(String.format("%.6f", x)) 给了我我想要的,但我正在寻找一些更简单的方法
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.000000999999999999547481118258862585613938723690807819366455078125)
与此相除,您应该除以
1e6
,正好是106,然后结果将是最接近0.07的浮点数(即0.07
或0.070000000000000006661338147750939242541790008544921875)。对不起,但是考虑到BigDecimal
有一个方法可以完全满足您的要求,我不明白为什么这个选项不在考虑之列。double
不能准确地表示0.07
。您所能“实现”的最好结果是0.070000000000000007
,为此,您只需执行double-want=int(给定*100)/100.0
@JoeC-Speed(和产生的垃圾)。这在我的实际用例中并不重要,但我很好奇。哇!真的这么简单吗?