我知道你永远不应该使用.NET中的==
相等运算符来比较浮点值,但是如果使用Math.Floor
将这两个数字放在一起可以安全吗?
我正在使用映射程序,并且地图的块存储在不同的“区域”文件中。我可以通过将世界坐标除以16来确定要检索的区域,并将结果放在地板上,从而获得区域坐标。
我实质上是在询问是否使用==
运算符将具有相同整数部分(例如4.3和4.8)的两个值进行比较。
答案 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.NaN
和Single.NaN
与==
进行比较时将返回false
(由Math.Floor
指示浮点规范)。
使用NaN
不会使这种情况更好。如果将任何特殊浮点值(NegativeInfinity
,PositiveInfinity
,Math.Floor
)传递给==
,则会以不变的方式返回它们。因此,通过Math.Floor
进行的比较仍会有奇怪的行为(Reference)
使用7.1
的主要效果将是更多浮动值将相互比较相等。例如,7.5
之后Math.Floor
和==
将相等。这本身并不是更好,但可以在您的应用程序的上下文中,但很难说它将没有更多的信息..你能否提供一些更详细的信息你认为{{1}}不安全吗?