当你在c#中从short转换为byte时会发生什么?



我有以下代码:

short myShort = 23948;
byte myByte = (byte)myShort;

现在我不期望myByte包含值23948。我猜它应该包含255(我认为是一个字节的最大值)。

然而,它包含140,这让我想知道为什么;幕后到底发生了什么?

请注意,我不是在找人来解决23948不能适合一个字节的问题,我只是想知道底层实现

Short是一个2字节类型,而一个字节就是一个字节。当您将两个字节转换为一个字节时,您将迫使系统使内容合适,并且原始字节(最重要的字节)中的一个丢失并且数据丢失。23948(二进制:0101 1101 1000 1100)的值剩下的是140,在二进制中转换为1000 1100。所以你要从:

0101 1101 1000 1100 (2 byte decimal value 23948)

:

          1000 1100 (1 byte decimal value 140)

只能通过显式强制转换来实现。如果您尝试将short赋值给字节而不进行强制类型转换,则编译器会抛出错误,因为可能会丢失数据:

不能隐式地将类型'short'转换为'byte'。一个显式的存在转换(您是否缺少强制类型转换?)

另一方面,如果你从一个字节转换为一个短类型,你可以隐式地进行,因为没有数据丢失。

using System;
public class MyClass
{
    public static void Main()
    {
        short myShort = 23948;
        byte myByte = (byte)myShort; // ok
        myByte = myShort; // error: 
        Console.WriteLine("Short: " + myShort);
        Console.WriteLine("Byte:  " + myByte);
        myShort = myByte; // ok
        Console.WriteLine("Short: " + myShort);
    }
}

算术溢出和未检查上下文:

using System;
public class MyClass {
    public static void Main() {
        unchecked {
            short myShort = 23948;
            byte myByte = (byte)myShort; // ok
            myByte = myShort; // still an error
            int x = 2147483647 * 2; // ok since unchecked
        }   
    }
}

基本上它只需要最后8位…但一般来说,当你发现一些令你惊讶的行为时,下一步应该是查阅规范。从第6.2.1节,我特别强调,在这种情况下相关的情况。

对于从整型到另一整型的转换,处理取决于转换发生的溢出检查上下文(第7.6.12节):

  • 在已检查的上下文中,如果源操作数的值在目标类型的范围内,则转换成功,但会抛出System。
  • 如果源操作数的值在目标类型的范围之外,则发生OverflowException。
  • 在未检查的上下文中,转换总是成功的,并按照如下步骤进行。
    • 如果源类型大于目的类型,则通过丢弃其"额外的"最高有效位来截断源值。然后将结果作为目标类型的值处理。
    • 如果源类型小于目的类型,则源值要么为符号扩展值,要么为零扩展值,以便与目的类型相同。如果源类型已签名,则使用Sign-extension;如果源类型为无符号,则使用零扩展。然后将结果作为目标类型的值处理。
    • 如果源类型与目的类型大小相同,则源值被视为目的类型的值。

看情况;在checked上下文中,你会得到一个大的异常;在unchecked上下文中(默认),您可以保留最后一个字节的数据,就像您这样做一样:

byte b = (byte)(value & 255);

在您的特定情况下,当您查看值:

的位时,该行为非常简单。
short myShort = 0x5D8C; // 23948
byte myByte = (byte)myShort; // myShort & 0xFF
Console.WriteLine("0x{0:X}", myByte); // 0x8C or 140

只保留最后8位。23948的二进制是101110110001100b。最后8位是10001100b,等于140。

当您将整型转换为"较小的"整型时,只考虑较小权重的位。从数学上讲,这就好像你用了模运算。所以你得到的值是140,因为23948模256等于140。

将long类型强制转换为int类型也使用相同的机制。

当您执行以下操作时,结果是相同的:

byte myByte = (byte)(myShort & 0xFF);

8位以上的所有内容都将被丢弃。23948 (0x5D8C)的下八位是140 (0x8C)。

嗯…因为当您将short(2字节)转换为byte(1字节)时,它只得到第一个字节,而23948的第一个字节表示140。

23948 % 256 = 140,转换后大部分有效字节丢失,因此输出为140

这就像当你有一个两位数的数字"97",把它转换成一个一位数,你失去了9,只留下了"7"

最新更新