如何在需要使用float时实际避免浮点错误?

时间:2013-04-21 16:38:11

标签: java floating-point precision floating-accuracy floating-point-precision

我试图使用一些UI按钮来影响3D模型的转换,以便将位置移动0.1或-0.1。

我的模型位置是一个三维浮点数,因此只需将0.1f添加到其中一个值会导致明显的舍入误差。虽然我可以使用像BigDecimal这样的东西来保持精度,但我仍然需要将它从浮点数转换回到最后的浮点数,它总是会导致愚蠢的数字使我的UI看起来像一团糟。

我可以很好地显示显示的值,但是舍入错误只会因为更多的编辑而变得更糟,并且它们使我的保存文件难以阅读。

那么当我需要使用float时,如何才能真正避免这些错误?

4 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

我会使用Rational课程。那里有很多 - this one看起来应该有效。

Rational呈现为float时,一个重要成本将是分母缩减为gcd时的成本。我发布的那个保持分子和分母始终处于完全缩小的状态,如果你总是增加或减去1/10,这应该是非常有效的。

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

您应该选择最适合您使用的实施方式。

答案 2 :(得分: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更多的精确数字和明智的舍入将不会看到这些错误。

答案 3 :(得分:-1)

如果你坚持使用花车: 避免错误的最简单方法是使用 exact 的浮点数,但是 接近所需的值

round(2 ^ n * value)* 1/2 ^ n。

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

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

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

长数链是二进制转换的人工制品, 实数的位数要少得多。

由于浮子是精确的,加法和减法都会 不会引入偏移误差,但总会如此 只要比特数是可预测的 不超过浮动值。

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

x = value * step。

随着步数增加或减少1, 精度将保留。