首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么将NaN转换为long会产生有效的结果?

为什么将NaN转换为long会产生有效的结果?
EN

Stack Overflow用户
提问于 2010-04-15 02:10:38
回答 5查看 1.7K关注 0票数 21

在下面的示例代码中,我将除以0,当我使用调试器单步执行时,(被除数/除数)会产生一个无穷大或NaN (如果除数是零)。当我将这个结果转换为长整型时,我得到一个有效的结果,通常类似于-9223372036854775808。为什么这个强制转换是有效的?为什么它不停止执行(例如抛出异常),而是分配一个任意值?

代码语言:javascript
运行
复制
double divisor = 0;
double dividend = 7;
long result = (long)(dividend / divisor);
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-04-15 02:42:38

为什么此强制转换有效?

如果在编译时知道转换可能成功或总是成功,则强制转换是有效的。仅当转换不可能成功时,强制转换才是非法的。(例如,将密封类型强制转换为它未实现的接口。)从double到long的转换可能会成功。因此,强制转换是有效的。

为什么它不停止执行(例如抛出异常),而是分配一个任意值?

因为你没有要求例外!该规范非常清楚地说明了预期行为是什么。参见第6.2.1节:

对于从浮点型或双精度型到整型类型的转换,处理过程取决于发生转换的溢出检查上下文:

在选中的上下文中,转换过程如下所示:

·如果操作数的值为NaN或infinite,则抛出System.OverflowException。

..。

在未检查的上下文中,转换始终成功,并按如下方式进行。

·如果操作数的值为NaN或infinite,则转换结果为目标类型的未指定值。

您在未检查的上下文中执行代码;您没有要求任何异常,所以没有得到任何异常。如果你想要一个例外,那就请求一个;使用一个检查过的上下文。

票数 24
EN

Stack Overflow用户

发布于 2010-04-15 02:14:24

默认情况下,未选中C#算术,因此无效操作不会抛出异常。

您可以使用checked block强制运行时检查溢出并引发异常,如下所示:

代码语言:javascript
运行
复制
checked {
    double divisor = 0;
    double dividend = 7;

    long result = (long)(dividend / divisor);
}

请注意,这将会有轻微的性能损失。

票数 14
EN

Stack Overflow用户

发布于 2010-04-15 02:48:35

在C#语言规范的第6.2.1节中明确记录了该行为:

对于从浮点型或双精度型到整型类型的转换,处理过程取决于发生转换的溢出检查上下文(§7.5.12):

在选中的上下文中,转换过程如下所示:

  • 如果操作数的值是NaN或System.OverflowException,则源操作数将向零四舍五入到最接近的整数值。如果此整数值在目标类型的范围内,则此值是抛出System.OverflowException的conversion.
  • Otherwise,的结果。

在未检查的上下文中,转换始终成功,并按如下方式进行。

如果操作数的值为NaN或infinite,则转换结果为目标type.

  • Otherwise,的未指定值。源操作数将向零四舍五入到最接近的整数值。如果此整数值在目标类型的范围内,则此值是conversion.

  • Otherwise,的结果,转换的结果是目标类型的未指定值。

添加粗体是为了强调。你已经有了无限和一个未检查的上下文。您得到的值是未指定的。使用checked关键字使其成为炸弹。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2639860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档