我有一个类似的课程:
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
吗?或者,当您使用它们执行操作时,浮点数是否会失去精度?
答案 0 :(得分:4)
它们不会失去精确度。以十进制描述某些浮点值存在不准确之处。对它们进行操作时,这些不准确性可能会相互叠加或相互抵消。
在你的情况下,0
可以用十进制和二进制浮点完全准确地描述,所以它应该有效。其他值可能不是,您应该(正如其他人指出的那样)不依赖于==
来获取浮点值。
在此处查看更多信息:http://floating-point-gui.de/
答案 1 :(得分:1)
归结为你不能完美地表示持有float
的32位内存中的每个浮点数(在所有无限方差中)。一个无法完美表示的数字只会有一个非常小的误差值,但它会存在。
例如,在最近的浮点表示中,1/3是(大致)0.333333343267。你有7个十进制数字的准确度,然后它会遇到一些障碍。所以假设你将1除以3,然后再乘以3.结果不是1,它是1.0000000298并且改变。所以(1/3)*3 =/= 1
。
这些表征性错误是直接比较浮点值被认为是不良实践的原因。
在您需要尽量减少这些小错误的影响的情况下,您应该尽一切可能阻止它们累积。例如,一次旋转一组坐标会给您带来不完美的结果,因为每次旋转操作引入的错误(使用sin
和cos
值不太可能具有完美的浮动表示)随着时间的推移积累。最好跟踪总角度变化并每次旋转原始矢量以获得更小的误差值。
另一个可以咬你的地方是for
循环。如果要以每步1/30000执行10,000步,请对循环变量使用int并将当前位置计算为除法。更慢,是的,但更准确。使用浮点数会累积错误,直到您只有大约3个可靠的有效十进制数字,而不是每次划分时超过7。
速度很好,但在某些情况下精度更高。
是的,这似乎很愚蠢,但这些错误确实可以增加。在某些地方不那么重要,在其他地方猖獗的错误工厂。
答案 2 :(得分:-2)
永远不要将浮点数与“==”进行比较。相反,你可以使用边框。例如,您可以执行类似
的操作,而不是比较== 0float border = 0.00000001;
if( (val - border) <= 0 && (val + border) >= 0)