Math.Max 与 Enumerable.Max
Math.Max(1f, float.NaN) == NaN
new[] { 1f, float.NaN }.Max() == 1f
为什么?
编辑:双也有同样的问题!
Jon Skeet reports today (source) that :
Math.Max(1f, float.NaN) == NaN
new[] { 1f, float.NaN }.Max() == 1f
Why?
Edit: same issue with double also!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
他还在这条后续推文中解释了原因:
He also explained the reason why in this follow-up tweet:
正如其他人所发布的,我在 Twitter 上发布了一个“原因”,因为它使用了记录中的 IComparable。
但这只会导致另一个“为什么”。特别是:
第一行表明 NaN 被视为大于 0。第二行表明 0 被视为大于 NaN。 (当然,这些都不能报告“这种比较没有意义”的结果。)
我的优点是可以看到所有回复推文,当然,包括 这些 两个:
As others have posted, I tweeted one sort of "why" - in that it's using
IComparable
as documented.That just leads to another "why" though. In particular:
The first line suggests that NaN is regarded as being greater than 0. The second line suggests that 0 is regarded as being greater than NaN. (Neither of these can report the result of "this comparison doesn't make sense", of course.)
I have the advantage of seeing all the reply tweets, of course, including these two:
(正确)答案的一项补充指出:即使您只阅读了简单的解释,两者的行为都如记录的那样。
此 IEnumerable 上的 Max() 扩展:
和 Math.Max():
请注意,NaN 不是一个值 - 因此可枚举的 Max 始终返回最大的值。 Math.Max 返回两个值中较大的一个,如果其中一个或两个值均为 NaN,则返回 NaN。
One addition to the (correct) answers stated: Both behave as documented, even if you read the simple explanation only.
Max() extension on this IEnumerable:
and Math.Max():
Note that NaN is not a value - so the enumerable Max always returns the largest value. Math.Max returns the greater of two values, or NaN if either or both of them is NaN.
Math.max 方法经过专门设计,如果您将 NaN 作为参数传递,则返回 NaN。请注意,这意味着 Math.max(a, b) 返回的值可能不大于任一参数; NaN 与任何其他值的任何运算符相比都会产生 false。
当在数组上使用 .Max() 时,默认实现(我相信)会扫描列表,查找大于任何其他值的值。由于 NaN 永远不会比较大于任何值的值,因此函数不会选择它。
简而言之,我认为您问题的答案是 Math.Max 很奇怪,而扩展方法 Max 则正确。
The Math.max method is specifically designed to return NaN if you pass NaN as an argument. Note that this means that it's possible for Math.max(a, b) to return a value that isn't greater than either argument; NaN compared with any operator to any other value yields false.
When using .Max() on the array, the default implementation (I believe) scans over the list looking for the value that compares greater than any other value. Since NaN never compares greater than anything, it won't be chosen by the function.
In short, I think the answer to your question is that Math.Max is weird, whereas the extension method Max is getting it right.
其他人已经发布了 John 发布的答案(扩展方法使用 IComparable,它返回任何内容,然后是 NaN),并且使用 Reflector 来查看 Math.Max 的实现显示了这一点,
因此您可以看到为什么它们返回不同的结果。如果你运行 (1.0 > double.NaN) 它将返回 false。
Others have posted the answer that John posted (the extension method uses IComparable which returns anything as > then NaN), and using reflector to look at the implementation of Math.Max shows this
So you can see why they return different results. If you run (1.0 > double.NaN) it will return false.
我认为 1 或 Nan 是否更大没有任何标准定义,因此由实现来决定。请注意,所有这些语句都会产生 false:
因此,如果
Max()
定义为:如果任何参数为 none,它将返回 a。
而且,如果任何参数为 Nan,则 max 的正确实现总是返回 b。
I suppose that whether 1 or Nan is greater is not defined by any standard, so it is left to the implementation to decide this. Note that all these statements produce false:
So if
Max()
is defined as:it will return a if any of the arguments is none.
And this, also correct implementation of max always return b if any of the arguments is Nan.