我试图使用一些UI按钮来影响3D模型的转换,以便将位置移动0.1或-0.1。
我的模型位置是一个三维浮点数,因此只需将0.1f添加到其中一个值会导致明显的舍入误差。虽然我可以使用像BigDecimal这样的东西来保持精度,但我仍然需要将它从浮点数转换回到最后的浮点数,它总是会导致愚蠢的数字使我的UI看起来像一团糟。
我可以很好地显示显示的值,但是舍入错误只会因为更多的编辑而变得更糟,并且它们使我的保存文件难以阅读。
那么当我需要使用float时,如何才能真正避免这些错误?
答案 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, 精度将保留。