C# 为什么此方法返回double.PositiveInfinity not DivideByZeroException?
我在VS2015 C#interactive中运行了以下代码片段,得到了一些非常奇怪的行为C# 为什么此方法返回double.PositiveInfinity not DivideByZeroException?,c#,exception-handling,infinity,dividebyzeroexception,C#,Exception Handling,Infinity,Dividebyzeroexception,我在VS2015 C#interactive中运行了以下代码片段,得到了一些非常奇怪的行为 > double divide(double a, double b) . { . try . { . return a / b; . } . catch (DivideByZeroException exception) . { . throw new ArgumentException("Argument b must be
> double divide(double a, double b)
. {
. try
. {
. return a / b;
. }
. catch (DivideByZeroException exception)
. {
. throw new ArgumentException("Argument b must be non zero.", exception);
. }
. }
> divide(3,0)
Infinity
> 3 / 0
(1,1): error CS0020: Division by constant zero
> var b = 0;
> 3 / b
Attempted to divide by zero.
>
为什么方法返回无穷大,而3/0抛出错误,3/b抛出格式化错误?我能强迫除法抛出一个错误而不是返回无穷大吗
如果我将方法重新格式化为
double divide(double a, double b)
{
if ( b == 0 )
{
throw new ArgumentException("Argument b must be non zero.", new DivideByZeroException());
}
return a / b;
}
新的DivideByZeroException是否包含与捕获的异常相同的信息和结构?这是因为您使用了
System.Double
正如dividebyzeroception所述,仅对整数类型和Decimal
引发异常
这是因为很难用“所谓”零来定义双精度值
正不确定性也是由零除以正得到的
股息和负不确定性是由零除以
负股息。
(来源:)
DivideByZeroException不适用于浮点类型。注意:当您尝试用零除法除法且除数为零时,可以得到NaN
为什么方法返回无穷大,而3/0抛出错误并返回3/
b抛出格式化错误
因为在第一种情况下,0不是整数,而是双精度。而在第二个是一个整数。您应该意识到这里的double是一个浮点数。所以它没有像整数那样的精确值。另一方面,一个整数可以由计算机以100%的精度表示
您可以找到一篇关于浮点数的非常好的文章。Java中的Int是2的补充。补码为2的整数没有任何位可用于存储特殊值,如无穷大或NaN,因此,由于结果不能用所需类型表示,因此必须抛出异常。浮点数没有这个问题(有一个位模式可用于无穷大),因此不需要例外。正如上面其他人所述,这是因为您使用double作为除数。您可以使用变量示例来证明这一点,但使用double
而不是var
> double a = 3;
> double b = 0;
> a/b
∞
这个问题不是我的错!尽管它也适用于C#。@codemonger从数学上讲,N/0并不等于无穷大。抛出异常比返回任何值更有意义,即使考虑到浮点数支持+/-无穷大的值。NaN比无穷大更合适。@KelsonBall NaN返回0/0。首先很难为浮点数定义0。感谢您指出这一点,我忘记了我使用var。将0指定为一个计算为无穷大的双精度文本。但是为什么正定、负定或NaN用于双精度,而不是抛出异常?这意味着代码以静默方式失败,计算仍在继续(并且这些值正在传播),其结果是a)输出可能是垃圾,b)用户甚至可能不知道存在问题(特别是如果代码是服务器上的后台无人值守进程),c)如果检测到问题,追溯它在代码中的第一次出现(可能会在很多地方出现)将是一件乏味的事情。@patrickjlee您将它标记为“失败”,但它不一定被视为失败。这完全取决于任务。IMHOSingle
和Double
在业务逻辑实现中经常被误用:根据我的经验,这些类型不精确会导致更大的问题,如果不小心处理。@sergey quixoticaxis ivanov我写金融软件已经30多年了,我从来没有遇到过这样的情况,即在计算结果生成无穷大、-无穷大或NaN后,软件继续运行是合适的。这种情况几乎总是由于数据中的意外情况或代码中的错误造成的,因此需要提醒用户存在问题。因此,在我看来,当前的默认行为(在.NET Core 3.0及更早版本和.NET 4.72及更早版本中)对此类应用程序来说是一个麻烦。@patrickjlee我完全喜欢关于30年来编写金融软件的评论。我为你感到高兴,如果你这么多年来一直使用不精确的浮点类型,而没有完全订购,而且从未击中自己的脚。但我见过的所有金融软件(应该说,我只见过交易台的软件)都使用精确的类型(并且不是用C语言编写的)。C#有一个很好的decimal
类型,不过它是为与金钱相关的任务量身定做的。对于与金钱无关的场景,如各种科学计算和3D建模,infinity和NaN非常常见。