NaN
,PositiveInfinity
或NegativeInfinity
对于float
和double
有什么好处?我们应该什么时候使用或避免它们?何时使用NaN或+/- Infinity?
如果有这些常数,为什么float.Parse("a")
会抛出错误而不是返回float.NaN
?
NaN
与null
有什么不同?为什么division by zero
甚至可以用于浮动类型?
NaN
,PositiveInfinity
或NegativeInfinity
对于float
和double
有什么好处?我们应该什么时候使用或避免它们?何时使用NaN或+/- Infinity?
如果有这些常数,为什么float.Parse("a")
会抛出错误而不是返回float.NaN
?
NaN
与null
有什么不同?为什么division by zero
甚至可以用于浮动类型?
他们没有那么多的东西,你使用,因为它们是你需要知道的东西:
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.Par se(“a”)抛出一个错误,而不是返回float.NaN?
double.NaN
实际上是在某种程度上数学定义 - 它是“定义为” 0.0/0.0
- 而改为“不是一个数字”意味着像double.Parse("a")
也应该返回double.NaN
,事实并非如此。为什么?
我的直觉是,因为这是不可能的,以确定是否收到double.NaN
是垃圾数据的结果(在字符串的情况下)或者实际定义一个不确定的数量,如零除以零。所以,为了区分这两种情况,double.Parse("a")
会抛出一个Exception
,我觉得它更准确。
为什么除以零浮动类型可能吗? – LZW 2013-02-27 18:16:19
@LZW简单的回答:因为你可以在以前的版本中编译/编译/运行'1.0/0.0',这会导致一个'DivideByZeroException',但是对于定义的'Infinity'和'NaN'值有理论上的应用 - 例如,WPF使用这两个表示“未设置”或“未定义”的大小等。 – JerKimball 2013-02-27 18:26:03
@LZW:在许多情况下,确定*是否可以评估浮点表达式,而不需要任何中间计算超出范围需要比那些在一切都在范围内时评估表达式所需的计算更昂贵的计算。允许代码尝试评估表达式,然后发现问题是否比需要代码提前检测有问题的条件便宜。 – supercat 2015-02-19 03:52:09
如果有这样的常数为什么
float.Parse("a")
抛出错误而不是返回float.NaN
?
,因为无论你列出的备选方案都在这里适用:
PositiveInfinity
和NegativeInfinity
是 - 即它们是表达式,如1/0
或-1/0
的结果。
NaN
是0/0
的结果 - 也就是,表达式的结果不是(通常)定义良好,也不会产生数字。
float.Parse("a")
就是这样的。无可否认,它可能会由NaN
代表,但是您无法区分输入无效的float
值(a
)和有效的float
值(NaN
)之间的用户。然而,这不是一个非常强烈的论点:NaN
是显式地一个无效数字的占位符,因此它可以想象用于表示无效的用户输入。
另一方面,还有其他类型有一个Parse
方法和其中没有NaN
价值存在(如int
)。对于这些类型,Parse
必须因此表示出现错误。这将是不一致的(因此糟糕的API设计)使不同类型的'Parse
方法行为不同。
JavaScript的parseFloat(“a”)返回NaN。 – LZW 2013-02-27 18:12:28
除了算术结果,无穷大值可以用来定义上下文的没有限制。
例如:父级WPF控件要求其一个子级在没有大小限制的情况下进行度量;即availableSize是PositiveInfinity时
这是给现实世界(而不是理论)例子的唯一答案。 – LZW 2013-02-28 11:19:33
无穷大是使用,因为它们是由浮点支持的运算系统的一部分。有各种各样的操作,例如除以零,其中无穷是有用的结果,并且在数学上是合理的。显然,没有直接的物理量可以是无限的(例如,你不能有无限多克),但无穷大可能是物理过程或人类用计算机建模的其他事物的数学模型的某个方面的有用值。
使用NaNs是因为算术系统不完整。也就是说,有些操作的输入值的正确数学结果不能在浮点内表示。例如,sqrt(-1)是一个合法的数学运算,但结果虚数i不能用浮点表示。所以NaN被用作占位符来表示值已经超出了浮点数。 NaN也可以用于其他目的,例如标记未被初始化的数据,以帮助调试。
float.Parse("a")
抛出错误而不是返回NaN,因为它不是合法的操作。此表达式不会执行数学运算,该运算在可表示数字之外具有适当的结果。这是一个实际的错误,所以会引发错误。
我喜欢这个答案;它解释了为什么Parse失败,因为你基本上试图统一两种没有关系的类型(float和string) – JerKimball 2013-02-27 19:35:53
要解决NAN和无限大,用这个:
if (Double.IsNaN(YourValue) || Double.IsInfinity(YourValue))
{
YourValue = 0;
}
你可以使用的TryParse而不是解析? – Liam 2013-02-27 16:46:01
由于数学运算而使用。 – Evgeny 2013-02-27 16:46:51
@Evgeny:有史以来最迷人的评论。 – 2013-02-27 16:49:10