Math.Max 与 Enumerable.Max

发布于 2024-10-11 08:27:18 字数 311 浏览 5 评论 0原文

Jon Skeet 今天报道 (来源) 那:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

妥活 2024-10-18 08:27:18

他还在这条后续推文中解释了原因:

这是因为扩展方法使用(并且记录为使用)IComparable 的实现,它将任何内容进行比较 > >南。

He also explained the reason why in this follow-up tweet:

It's because the extension method uses (and is documented to use) the implementation of IComparable, which compares anything as > NaN.

不美如何 2024-10-18 08:27:18

正如其他人所发布的,我在 Twitter 上发布了一个“原因”,因为它使用了记录中的 IComparable。

但这只会导致另一个“为什么”。特别是:

Console.WriteLine(Math.Max(0, float.NaN));  // Prints NaN
Console.WriteLine(0f.CompareTo(float.NaN)); // Prints 1

第一行表明 NaN 被视为大于 0。第二行表明 0 被视为大于 NaN。 (当然,这些都不能报告“这种比较没有意义”的结果。)

我的优点是可以看到所有回复推文,当然,包括 这些 两个

这可能看起来不寻常,但这是正确的答案。当且仅当所有元素均为 NaN 时,数组的 max() 为 NaN。请参阅 IEEE 754r。

此外,Math.Max 使用 IEEE 754r 全排序谓词,它指定 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:

Console.WriteLine(Math.Max(0, float.NaN));  // Prints NaN
Console.WriteLine(0f.CompareTo(float.NaN)); // Prints 1

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:

It may seem unusual, but that's the right answer. max() of an array is NaN iff all elements are NaN. See IEEE 754r.

Also, Math.Max uses IEEE 754r total ordering predicate, which specifies relative ordering of NaN vs. others.

¢蛋碎的人ぎ生 2024-10-18 08:27:18

(正确)答案的一项补充指出:即使您只阅读了简单的解释,两者的行为都如记录的那样。

此 IEnumerable 上的 Max() 扩展:

返回a中的最大值
单个值的序列。

和 Math.Max():

[返回]参数val1或val2,
以较大者为准。如果 val1、val2 或
val1 和 val2 都等于 NaN,
返回 NaN。

请注意,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:

Returns the maximum value in a
sequence of Single values.

and Math.Max():

[Returns] Parameter val1 or val2,
whichever is larger. If val1, val2, or
both val1 and val2 are equal to NaN,
NaN is returned.

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.

勿忘心安 2024-10-18 08:27:18

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.

情绪操控生活 2024-10-18 08:27:18

其他人已经发布了 John 发布的答案(扩展方法使用 IComparable,它返回任何内容,然后是 NaN),并且使用 Reflector 来查看 Math.Max 的实现显示了这一点,

public static double Max(double val1, double val2)
{
    if (val1 > val2)
    {
        return val1;
    }
    if (double.IsNaN(val1))
    {
        return val1;
    }
    return val2;
}

因此您可以看到为什么它们返回不同的结果。如果你运行 (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

public static double Max(double val1, double val2)
{
    if (val1 > val2)
    {
        return val1;
    }
    if (double.IsNaN(val1))
    {
        return val1;
    }
    return val2;
}

So you can see why they return different results. If you run (1.0 > double.NaN) it will return false.

↙温凉少女 2024-10-18 08:27:18

我认为 1 或 Nan 是否更大没有任何标准定义,因此由实现来决定。请注意,所有这些语句都会产生 false:

        Console.WriteLine("1>Nan {0}]", 1.0 > double.NaN);
        Console.WriteLine("1<Nan {0}]", 1.0 < double.NaN);
        Console.WriteLine("1>=Nan {0}]", 1.0 >= double.NaN);
        Console.WriteLine("1<=Nan {0}]", 1.0 <= double.NaN);

因此,如果 Max() 定义为:

if (a<=b) return b else return a;

如果任何参数为 none,它将返回 a。

if (a>b) return a else return b;

而且,如果任何参数为 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:

        Console.WriteLine("1>Nan {0}]", 1.0 > double.NaN);
        Console.WriteLine("1<Nan {0}]", 1.0 < double.NaN);
        Console.WriteLine("1>=Nan {0}]", 1.0 >= double.NaN);
        Console.WriteLine("1<=Nan {0}]", 1.0 <= double.NaN);

So if Max() is defined as:

if (a<=b) return b else return a;

it will return a if any of the arguments is none.

if (a>b) return a else return b;

And this, also correct implementation of max always return b if any of the arguments is Nan.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文