2

我有这样的课:

public class Test
{
    public void CheckValue(float val)
    {
        if (val == 0f)
        {
            //Do something
        }
    }
}

//Somewhere else..
void SomeMethod
{
    Test t = new Test();
    t.CheckValue(0f);
}

是否保证检查if (val == 0f)会返回true?或者浮点数只会在您对它们执行操作时失去精度?

4

3 回答 3

4

他们不会失去精确度。用十进制描述一些浮点值是不准确的。在对它们进行操作时,这些不准确性可能会叠加或相互抵消。

在您的情况下,0可以用十进制和二进制浮点完全准确地描述,所以它应该可以工作。其他值可能不是,您应该(正如其他人指出的那样)不要依赖==浮点值。

在此处查看更多信息:http: //floating-point-gui.de/

于 2013-03-05T10:23:00.243 回答
1

归结为,您不能完美地表示在 32 位内存中保存的每个浮点数(在所有它们的无限方差中)float。一个不能完美表示的数字只会有一个很小的误差值,但它会在那里。

例如,在最近的浮点表示中,1/3 是(大约)0.333333343267。你有 7 位十进制数字的准确性,然后它遇到了一些障碍。因此,假设您将 1 除以 3,然后再乘以 3。结果不是 1,而是 1.0000000298 并发生变化。所以(1/3)*3 =/= 1

这些表示错误就是为什么直接比较浮点值被认为是不好的做法。

在您需要尽量减少这些小错误的影响的情况下,您应该尽一切可能阻止它们累积。例如,一次稍微旋转一组坐标会给您带来不完美的结果,因为每个旋转操作(使用不太可能具有完美浮点表示的值)引入的错误sincos随着时间的推移而累积。更好地跟踪总角度变化并每次旋转原始向量以获得更小的误差值。

另一个可能会咬你的地方是一个for循环。如果您想以每步 1/30000 执行 10,000 步,请使用 int 作为循环变量并将当前位置计算为除法。更慢,是的,但更准确。使用浮点数会累积错误,直到您只有大约 3 个可靠的十进制有效数字,而不是每次除法时超过 7 个。

速度很好,但在某些情况下精度更好。

是的,这看起来很傻,但是这些错误确实会增加。在某些地方并不那么重要,而在其他地方则猖獗的错误工厂。

于 2013-03-05T11:36:46.517 回答
-2

您永远不应该将浮点数与“==”进行比较。相反,您可以使用边框。例如,而不是比较 == 0 你可以做类似的事情

float border = 0.00000001;
if( (val - border) <= 0 && (val + border) >= 0)
于 2013-03-05T10:23:58.573 回答