4

我正在尝试使用一些 UI 按钮来影响 3D 模型的翻译,以将位置移动 0.1 或 -0.1。

我的模型位置是一个三维浮点数,所以简单地将 0.1f 添加到其中一个值会导致明显的舍入误差。虽然我可以使用 BigDecimal 之类的东西来保持精度,但我仍然必须将它从浮点数转换为最后的浮点数,它总是会导致愚蠢的数字,让我的 UI 看起来像一团糟。

我可以只显示显示的值,但舍入错误只会随着更多的编辑而变得更糟,它们使我的保存文件很难阅读。

那么当我需要使用浮点数时,如何真正避免这些错误呢?

4

4 回答 4

2

Kahan 求和和成对求和算法有助于减少浮点错误。 这是 Kahan 算法的一些 Java 代码

于 2013-04-21T16:50:29.620 回答
1

我会使用一个Rational类。那里有很多 -这个看起来应该可以工作。

一个重要的成本是当Rational被渲染为 afloat时,一个当分母被减少到gcd. 我发布的那个让分子和分母始终处于完全减少的状态,如果你总是加或减 1/10,这应该是非常有效的。

实现保持标准化的值(即具有一致的符号)但未减少。

您应该选择最适合您的使用的实现。

于 2013-04-21T16:54:51.997 回答
0

一个简单的解决方案是使用固定精度。即你想要的整数 10 倍或 100 倍。

float f = 10;
f += 0.1f;

变成

int i = 100;
i += 1;  // use an many times as you like
// use i / 10.0 as required.

在任何情况下我都不会使用float,因为你得到的舍入错误比double几乎没有好处(除非你有数百万个浮点值) double为你提供了 8 位以上的精度,并且通过合理的舍入将不会看到这些错误。

于 2013-04-21T21:05:40.853 回答
-1

如果您坚持使用浮点数:避免错误的最简单方法是使用精确但接近所需值的浮点数

圆形(2^n * 值)* 1/2^n。

n 是位数,值要使用的数字(在您的情况下为 0.1)

在您的情况下,精度越来越高:

n = 4 => 0.125
n = 8(字节)=> 0.9765625
n = 16(短)=> 0.100006103516 ....

长数链是二进制转换的产物,实数的位数少得多。

由于浮点数是精确的,因此加法和减法不会引入偏移误差,但只要位数不超过浮点值所保持的长度,就始终是可预测的。

如果您担心使用此解决方案会影响您的显示(因为它们是奇数浮点数),请仅使用和存储整数(步长增加 -1/1)。内部设置的最终值是

x = 值 * 步长。

随着步长增加或减少 1,精度将保持不变。

于 2013-04-21T19:58:39.610 回答