c#中有符号整型和无符号整型之间的窄型强制转换

本文关键字:整型 窄型 转换 之间 无符号 符号 | 更新日期: 2023-09-27 18:18:07

我想确认一下c# (5.0, . net Framework 4.0/4.5)中整型的窄型强制转换的工作方式。底线:当在有符号和无符号类型之间进行转换时,我能确保整型的底层字节在顺序和值方面保持不变吗?

假设我做了以下操作:

short shortVal = -20000;
ushort ushortVal = (ushort)shortVal;
现在,我所做的实验表明,以下两个字节数组中的字节:
byte[] shortBytes = BitConverter.GetBytes(shortVal);
byte[] ushortBytes = BitConverter.GetBytes(ushortVal); 

不不同。我已经做了这个确切的实验,从shortushort的显式窄化转换,shortVal的值在Int16.MinValueInt16.MaxValue的范围内。所有2^16种情况都没问题。但是,实际解释的值自然会被重新解释,因为字节保持不变。我假设有符号整型使用2的补码来表示有符号值(这是真的吗?)

我需要知道,我是否可以指望这些转换总是"字节安全的"——就像不改变底层字节及其顺序一样。这也适用于从无符号到有符号的转换。这些转换是彼此完全相反的吗?我主要关注short/ushort和int/int。但是我们对所有整型都感兴趣。

这些细节可能与c#和CLR背后的技术实现有关。我在这里严格关注Windows 32/64位的CLR。

c#中有符号整型和无符号整型之间的窄型强制转换

这是相当棘手的。

CLR确实在x86/x64体系结构上使用2的补码来表示有符号的整数(正如您在测试中观察到的),并且在不久的将来不太可能改变,因为体系结构本身对它有很好的支持。可以肯定的是,它将在一段时间内保持这种状态。

另一方面,我没有在CLI或c#规范中找到任何提及这一点,所以你不能指望它,特别是面对其他架构和/或CLI实现。

这取决于你想在什么地方使用它。如果可能的话,我会避免依赖于这样的实现细节,并使用更高级别的序列化工具来转换到/从任何二进制表示。