【问题标题】:Shortest way of checking if Double is "NaN"检查 Double 是否为“NaN”的最短方法
【发布时间】:2014-07-11 12:15:41
【问题描述】:

使用Double.PositiveInfinity 作为参数调用Double.IsNaN() 时,结果为假。这违背了我的直觉,因为无穷大不是一个数字。显然“NaN”仅以.NET 中的常量形式存在,这是由 IEEE 标准描述的还是自定义实现细节?是否有比以下更短的方法来检查 Double 是否为“NaN”:

(Double.IsNaN(d) || Double.IsPositiveInfinity(d) || Double.IsNegativeInfinity(d))

(Double.IsNaN(d) || Double.IsInfinity(d))

【问题讨论】:

  • 除非您只是创建自己的自定义包装函数,否则不会期望它变得更短。
  • NaN 在 IEEE 标准中有所描述,是的(实际上它稍微复杂一些,具有相当的 NaN 和信令 NaN)。它是浮点数的可能值,而不是“除了普通旧数字之外的任何东西”的类别。
  • 我很少遇到应该以相同方式处理 NaN 和无穷大的情况。许多计算工作正常,并得到有意义的结果,数据中的无穷大。在广泛使用 IsNanOrInfinity 函数之前,请仔细查看它是否真的对您的计算有意义。
  • @PatriciaShanahan - 幸运的是我没有做任何浮点计算。我正在验证两个代表Double.MinValueDouble.MaxValue 之间范围的双精度数。据我所知,它们中的任何一个都是 NaN 没有意义。
  • 你能接受 Roman Marusyk 的回答是正确的吗?从 .net 5 开始,接受的答案已经过时了。

标签: c# .net floating-point


【解决方案1】:

正如 MSDN 所说,NaN 表示结果未定义。定义无穷大的结果:

当运算结果为 不明确的。例如,零除以零的结果是 NaN,如 以下示例显示。 (但请注意,除以非零数 由零返回 PositiveInfinity 或 NegativeInfinity,具体取决于 在除数的符号上。)

因此,将无穷大视为 NaN 并不是一个好主意。您可以编写扩展方法来检查值是否不是 NaN 或无穷大:

// Or IsNanOrInfinity
public static bool HasValue(this double value)
{
    return !Double.IsNaN(value) && !Double.IsInfinity(value);
}

【讨论】:

  • 使用扩展方法非常简洁。我想没有比这更好的了。
  • 我猜 HasValue 会产生误导,因为无穷大一个值。
  • @Mario 同意,这就是为什么另一个建议的名称是 IsNanOrInfinity
  • @SergeyBerezovskiy:IsFinite 是一个常见的约定。
【解决方案2】:

您不再需要 SergeyBerezovskiy 回答的扩展。

doubleIsFinite() 方法来检查双精度数是否为有限数(不是NaNInfinity):

double.IsFinite(d)

查看.Net Framework.Net Core中的源代码

【讨论】:

  • 应该注意,这仅适用于 .Net Standard 2.1,对于坚持使用 2.0 的人(如 Unity 开发人员),此功能在此答案后近 2 年仍然不可用。
【解决方案3】:

Double 类型中有三个特殊值,它基于IEEE standard 754。一个是正​​无穷大,另一个是负无穷大,最后一个是非数(NaN)。 Double.IsNaN 方法所做的只是检查变量中的值是否是这个特殊的 NaN 值。

【讨论】:

    【解决方案4】:

    如果您希望 double 的值始终为数字,则可以使用此 FiniteOrDefault 扩展名。当然是受到Sergey Berezovskiy's answer的启发。

    public static bool HasValue(this double value)
    {
        return !double.IsNaN(value) && !double.IsInfinity(value);
    }
    
    /// <summary>
    /// Returns zero when double is NaN or Infinte
    /// </summary>
    public static double FiniteOrDefault(this double value)
    {
        return value.HasValue() ? value : default;
    }
    

    这样,以下代码的可读性会更高:

    Rect dimensions = new Rect
    {
        X = Canvas.GetLeft(Control).FiniteOrDefault(),
        Y = Canvas.GetTop(Control).FiniteOrDefault(),
        Width = Control.ActualWidth.FiniteOrDefault(),
        Height = Control.ActualHeight.FiniteOrDefault()
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-11
      • 1970-01-01
      • 2018-02-03
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      相关资源
      最近更新 更多