gpt4 book ai didi

c# - 如何使用泛型测试 NaN(或者为什么 NaN.Equals(NaN) == true)?

转载 作者:行者123 更新时间:2023-11-30 13:27:21 29 4
gpt4 key购买 nike

我需要在数组中找到minma​​x值(不考虑可能的NaN值在这个数组中)。

这只使用 double 会很容易,但是这些 FindMin 和 FindMax 函数必须使用泛型类型。

我尝试以这种方式测试通用 NaN:

bool isNaN<T>(T value) where T : IEquatable<T>
{
return !value.Equals(value);
}

但是 Equalsdouble.NaN 返回 true ??!!

我现在有这样的解决方法:

bool isNaN<T>(T value) where T : IEquatable<T>
{
var d = value as double?;
if (d.HasValue) { return double.IsNaN(d.Value); }

return !value.Equals(value);
}

我的问题更多是了解为什么第一个解决方案不起作用,这是一个错误吗?

你可以找到小测试代码here

最佳答案

我会简单地使用 double.IsNaN并让编译器隐式转换 float需要的成员:

float myFloat = float.NaN; // or 0.0f / 0.0f;
double myDouble = double.NaN; // or 0.0 / 0.0;

Console.WriteLine(double.IsNaN(myFloat));
Console.WriteLine(double.IsNaN(myDouble));

在堆栈上“浪费”了非常少量的内存并使用了强制转换操作调用,但是嘿嘿它是通用的足够来满足任何可以容纳“数字”NaN 的类型。

或者,使用 float.IsNaN似乎适用于基本测试,但需要显式向下转换 double (向下转换 double.NaN0.0 / 0.0 似乎有效,因为它会正确报告 NaN)。

您不能以任何清洁度(或者根本不能 100% 确定)对值类型的子集进行一般约束,所以我不会费心去追逐 <T>个人路线。


如果你想要一个通用的解决方案,这意味着被调用者不需要关心传入的内容,你可以执行以下操作:

    static bool IsNaN(dynamic d)
{
float dub;

try
{
dub = (float)d;
return float.IsNaN(dub);
}
catch (RuntimeBinderException)
{
}

return false;
}

然而,这会招致装箱。还要注意 dynamic是必需的并且object将不起作用,因此这也会调用 DLR(并且还会吞下所有 RuntimeBinderException s)。

关于c# - 如何使用泛型测试 NaN(或者为什么 NaN.Equals(NaN) == true)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12109345/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com