【发布时间】:2017-03-01 16:27:04
【问题描述】:
将 double.NaN 转换为 int 将为 0。
Console.WriteLine(unchecked((int)double.NaN)); // 0
但是,将 double.NaN 分配给变量然后强制转换为 int 将是 -2147483648。
double value = double.NaN;
Console.WriteLine (unchecked ((int) value)); // -2147483648
Console.WriteLine ((int) value); // -2147483648
为什么结果会根据是否赋值给变量而改变?
C# 规范
6.2.1 显式数字转换
- 在检查的上下文中,转换过程如下:
- 如果操作数的值为 NaN 或无穷大,则会引发 System.OverflowException。
- 否则,源操作数将向零舍入到最接近的整数值。如果这个整数值在目标类型的范围内,那么这个值就是转换的结果。
- 否则,将引发 System.OverflowException。
- 在未经检查的上下文中,转换始终成功,并按如下方式进行。
- 如果操作数的值为 NaN 或无穷大,则转换的结果是目标类型的未指定值。
- 否则,源操作数将向零舍入到最接近的整数值。如果这个整数值在目标类型的范围内,那么这个值就是转换的结果。
- 否则,转换的结果是目标类型的未指定值。
环境
- 编译器:Visual Studio 2013
- Rimtime:.NET Framework 4.6.0
- 操作系统:Windows 10 版本 1607
- CPU:英特尔酷睿 i7 920
窗户:
Console.WriteLine(Environment.OSVersion); // Microsoft Windows NT 6.2.9200.0
Console.WriteLine(Environment.Version); // 4.0.30319.42000
【问题讨论】:
-
我建议你看看 IL - 我怀疑 compiler 正在执行第一次转换,只是将结果硬编码为 0。而在你的变量情况下您是在要求 CLR 执行此操作。
-
我无法复制。
Console.WriteLine(unchecked((int)double.NaN));在我尝试时打印-2147483648。 -
您使用的是什么版本的编译器?我也没有收到
0。 -
这让我想起了无数“为什么
int *c; printf("%d", *c);print 37` 人们问的关于 C 的未定义行为问题。规范告诉你这将是一个未指定的数字。你甚至不应该感到惊讶如果每次运行程序时它都是不同的数字。 -
你在Nasal Deamons的领域,它返回两个不同的数字,因为它“感觉像它”。
标签: c#