何时使用 NaN 或 +/-Infinity?

Posted

技术标签:

【中文标题】何时使用 NaN 或 +/-Infinity?【英文标题】:When to use NaN or +/-Infinity? 【发布时间】:2013-02-13 13:56:00 【问题描述】:

NaNPositiveInfinityNegativeInfinityfloatdouble 有什么好处?我们什么时候应该使用或避免使用它们?

如果有这样的常量,为什么float.Parse("a")会抛出错误而不是返回float.NaN

NaNnull 有何不同?为什么 division by zero 甚至可以用于浮动类型?

【问题讨论】:

你可以使用 TryParse 而不是 Parse? 用于数学运算。 @Evgeny:有史以来最模糊的评论。 @Liam 我的问题不是关于如何解析,我想知道为什么在强类型环境中有 NaN。 what does NaN mean for doubles? 的可能重复项 【参考方案1】:

使用无穷大是因为它们是浮点支持的算术系统的一部分。有各种运算,例如除以零,其中无穷大是一个有用的结果并且在数学上是合理的。显然,没有直接的物理量可以是无限的(例如,您不能有无限多的克),但对于物理过程的数学模型或人类使用计算机建模的其他事物的数学模型的某些方面,无限可能是一个有用的值。

使用 NaN 是因为算术系统不完整。也就是说,有些运算的输入值无法在浮点内表示正确的数学结果。例如,sqrt(-1) 是一个合法的数学运算,但结果虚数 i 不能用浮点数表示。因此,NaN 用作占位符,表示值已超出浮点数。 NaN 还可用于其他目的,例如标记未初始化的数据,以帮助调试。

float.Parse("a") 抛出错误而不是返回 NaN,因为它不是合法的操作。此表达式不执行具有可表示数字之外的正确结果的数学运算。这是一个实际的错误,所以它会抛出一个错误。

【讨论】:

我喜欢这个答案;它解释了 Parse 失败的原因,因为您基本上是在尝试统一两种没有关系的类型(浮点数和字符串)【参考方案2】:

它们不是你使用的东西,因为它们是你需要注意的东西:

double hmm = 1.0 / 0.0;
double hmm2 = -1.0 / 0.0;
double hmm3 = 0.0 / 0.0;
Console.WriteLine("1/0 == 0", hmm);
Console.WriteLine("-1/0 == 0", hmm2);
Console.WriteLine("0/0 == 0", hmm3);

输出:

1/0 == Infinity
-1/0 == -Infinity
0/0 == NaN

编辑: 至于这个问题:

如果有这样的常量,为什么 float.Parse("a") 会抛出错误而不是返回 float.NaN?

double.NaN 在某种程度上实际上是一个数学定义——它被“定义”为0.0/0.0——而“不是一个数字”这个词意味着像double.Parse("a") 这样的东西也应该返回double.NaN,它没有.为什么?

我的预感是因为无法确定您收到的double.NaN 是垃圾数据(在字符串的情况下)还是不确定数字的实际定义的结果,就像零除以零。所以,为了区分这两种情况,double.Parse("a") 抛出一个Exception,我觉得更准确。

【讨论】:

为什么浮点类型可以被零除? @LZW 简单的回答:因为您可以输入/编译/运行1.0/0.0 - 在过去,这会导致DivideByZeroException,但“已定义”InfinityNaN 值 - 例如,WPF 使用这两者来表示“未设置”或“未定义”大小等。 @LZW:在许多情况下,确定是否浮点表达式可以在没有任何超出范围的中间计算的情况下进行评估,这需要比所需计算更昂贵的计算当一切都在范围内时评估表达式。因此,允许代码尝试评估表达式然后找出是否存在问题比要求代码提前检测有问题的条件更便宜。【参考方案3】:

如果有这样的常量,为什么float.Parse("a") 会抛出错误而不是返回float.NaN

因为您列出的备选方案均不适用于此处:

PositiveInfinityNegativeInfinity 就是这样 - 即它们是 1/0-1/0 等表达式的结果。

NaN0/0 的结果 - 即一个表达式,其结果(通常)没有明确定义并且不会产生数字。

float.Parse("a") 不是那样的。诚然,它可能由NaN 表示,但是您无法区分用户输入了无效的float 值(a)和有效的float 值(NaN)。然而,这不是一个非常有力的论据:NaN 明确是一个无效数字的占位符,因此可以想象它可以用来表示无效的用户输入。

另一方面,还有其他类型具有Parse 方法并且不存在NaN 值(例如int)。对于这些类型,Parse必须因此发出错误信号。使不同类型的 Parse 方法表现不同会是不一致的(因此是糟糕的 API 设计)。

【讨论】:

javascript 的 parseFloat("a") 返回 NaN。【参考方案4】:

除了算术的结果外,无穷大值可用于定义上下文的无限制。

例如:在没有大小限制的情况下,父 WPF 控件要求其子之一测量自身;即availableSize是PositiveInfinity

参考:MeasureOverride

【讨论】:

这是给出真实世界(非理论)示例的唯一答案。【参考方案5】:

要解析 NAN 和无穷大,请使用:

if (Double.IsNaN(YourValue) || Double.IsInfinity(YourValue))

   YourValue = 0;

【讨论】:

以上是关于何时使用 NaN 或 +/-Infinity?的主要内容,如果未能解决你的问题,请参考以下文章

js-20170817-JSON对象

如何在 NaN 和 Infinity 上使用条件类型

JSON.stringify(),JSON.parse()

java中Infinity(无限)和NaN

使用 Infinity 和 NaN 禁用异常

浮点数或双精度数的 NaN 和 Infinity 如何存储在内存中?