C# 中的可空双 NaN 比较

Posted

技术标签:

【中文标题】C# 中的可空双 NaN 比较【英文标题】:Nullable double NaN comparison in C# 【发布时间】:2012-11-15 20:15:21 【问题描述】:

我有 2 个可为空的双精度值,一个期望值和一个实际值(我们称它们为 value 和 valueExpected)。使用 100 * (value / valueExpected) 找到百分比。但是,如果 valueExpected 为零,则返回 NaN。到目前为止一切都很好。

现在,如果我需要检查该值,看看它是否为 NaN,我该怎么办?通常可以使用:

if (!Double.IsNaN(myDouble))

但这不适用于可空值(IsNaN 仅适用于不可为空的变量)。我已更改代码以进行检查(valueExpected == 0),但我仍然很好奇 - 有什么方法可以检查可为空的 NaN?

编辑:当我说代码不起作用时,我的意思是它不会编译。首先测试 null 不起作用。

【问题讨论】:

【参考方案1】:

使用newer Roslyn C# versions 中的模式匹配,double.NaN 是使用IsNaN 进行测试的有效模式(也就是说,它的工作方式与Equals() 不同,其中NaN 永远不等于NaN,由IEEE 浮点数指定点标准)。

因此您现在可以这样做:

double? myDouble = something;
if (myDouble is double and not double.NaN)
   Console.WriteLine("A number");

为了测试NaN,甚至可以这样缩短:

double? myDouble = something;
if (myDouble is double.NaN)
   Console.WriteLine("Not a number and not NULL");

【讨论】:

【参考方案2】:

使用 C# 7.0 Pattern matching 组合 null + NaN 检查可以这样写:

double? d = whatever;
if(d is double val && double.IsNaN(val))
   Console.WriteLine(val);

优势在于手头的局部范围变量val,它既不是null,也不是double.NaN,甚至可以在if之外使用。

【讨论】:

【参考方案3】:

我遇到了同样的问题,我通过投射双精度解决了它?带双

double.IsNaN((double)myDouble)

如果是 NaN 则返回 true,否则返回 false

【讨论】:

请注意,每当myDouble == null 时,这将不起作用(抛出异常myDouble == null,这是具有可空性...【参考方案4】:

你也可以使用

if (!Double.IsNaN(myDouble ?? 0.0))

最内层括号中的值要么是myDouble(去掉了Nullable<> 包装),如果它是非空的,或者只是0.0,如果myDoublenull。硒?? Operator (C#)。

【讨论】:

【参考方案5】:

对于所有Nullable<T> 实例,您首先检查bool HasValue 属性,然后您可以访问T Value 属性。

double? d = 0.0;        // Shorthand for Nullable<double>
if (d.HasValue && !Double.IsNaN(d.Value)) 
    double val = d.Value;

    // val is a non-null, non-NaN double.

【讨论】:

也许只是视觉工作室阻止了我。我确实有类似的东西:` if(myDouble != null) if (!Double.IsNaN(myDouble)) //做点什么! ` 但是这个和你的代码没有编译,它仍然不喜欢使用 IsNaN,即使在 'is null' 检查之后。 你看到变量名“d”后面的“.Value”了吗。 d.Value 是一个双精度值,它绝对应该编译。 我的代码编译得很好。您添加的“为空”检查不会改变任何内容。您的代码仍然不正确。 myDoubleNullable&lt;double&gt;,而 IsNaN() 需要 double。您必须使用.Value 属性。 啊!是的,这行得通。因此 .value 会将其用作不可为空的类型。谢谢!我错过了 .value。 您是否碰巧查看了文档?当涉及到这些事情时,MSDN 是您最好的朋友。 .Value 实际上返回 实际 基础价值。 Nullable&lt;T&gt; 实际上只是一个 T 和一个 bool 在引擎盖下。

以上是关于C# 中的可空双 NaN 比较的主要内容,如果未能解决你的问题,请参考以下文章

c# 中的可空类型是啥?

C# 8中的可空引用类型

使用 Protobuf-net 序列化可空双精度列表的问题

使用 C# 8 的可空引用类型

SQL更新语句 - 比较可空字段的值

C# 的可空合并运算符(??)到底是怎样的宝宝?