使用相等运算符比较两个被填充的双精度数是否安全?

时间:2011-03-02 18:11:15

标签: c# .net floating-point equality

我知道你永远不应该使用.NET中的==相等运算符来比较浮点值,但是如果使用Math.Floor将这两个数字放在一起可以安全吗?

我正在使用映射程序,并且地图的块存储在不同的“区域”文件中。我可以通过将世界坐标除以16来确定要检索的区域,并将结果放在地板上,从而获得区域坐标。

我实质上是在询问是否使用==运算符将具有相同整数部分(例如4.3和4.8)的两个值进行比较。

3 个答案:

答案 0 :(得分:5)

浮点比较的一般问题是它们很容易产生舍入误差。当您使用1.2之类的值(不能完全表示为小数)时,将其乘以100并将其与120的相等性进行比较。建议总是比较差异:

var a = 1.2;
a *= 100;

if (a - 120 < 0.0001)
{
}

然而,Math.Floor操作始终会产生整数值。也就是说,任何小数值都将被截断,并且 exact 整数值将被保留。

因此,如果您的语义确实使用楼层,那么您就是安全的。

但是,如果您真的想要舍入,那么请改用Math.Round()。

答案 1 :(得分:4)

嗯,这取决于你想要做什么。

这会告诉你地板值是否相等 - 但是如果一个输入只是一个smidge 低于2,而一个输入只是一个小于 2,那么尽管它们之间的差异很小,但它们将被视为不同。

你的情况可以吗?在某些情况下,它会在某些情况下不会。

答案 2 :(得分:2)

我认为你的问题是基于一个错误的假设。使用== in .Net比较浮点值是完全安全的。与==和浮点值相关联的唯一奇怪行为是Double.NaNSingle.NaN==进行比较时将返回false(由Math.Floor指示浮点规范)。

使用NaN不会使这种情况更好。如果将任何特殊浮点值(NegativeInfinityPositiveInfinityMath.Floor)传递给==,则会以不变的方式返回它们。因此,通过Math.Floor进行的比较仍会有奇怪的行为(Reference

使用7.1的主要效果将是更多浮动值将相互比较相等。例如,7.5之后Math.Floor==将相等。这本身并不是更好,但可以在您的应用程序的上下文中,但很难说它没有更多的信息.​​.你能否提供一些更详细的信息你认为{{1}}不安全吗?