在C#中从短到节转换时会发生什么?

时间:2011-09-27 21:03:47

标签: c# casting byte short

我有以下代码:

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

现在我没想到myByte包含值23948.我猜它会包含255(我相信一个字节的最大值)。

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

请注意,我不是在找人解决23948无法容纳的问题,我只想知道底层实现

10 个答案:

答案 0 :(得分:15)

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'隐式转换为'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
        }   
    }
}

答案 1 :(得分:6)

基本上它只需要最后8位......但总的来说,当你发现一些令你惊讶的行为时,下一步应该是参考规范。从第6.2.1节开始,特别强调我的情况,以及与此案相关的情况。

  

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

     
      
  • 在已检查的上下文中,如果源操作数的值在目标类型的范围内,则转换成功,但如果源操作数的值超出目标类型的范围,则抛出System.OverflowException。 / LI>   
  • 在未选中的上下文中,转换始终成功,并按如下方式进行。   
        
    • 如果源类型大于目标类型,则通过丢弃其“额外”最高有效位来截断源值。然后将结果视为目标类型的值。
    •   
    • 如果源类型小于目标类型,则源值可以是符号扩展或零扩展,以便与目标类型的大小相同。如果源类型已签名,则使用符号扩展;如果源类型是无符号的,则使用零扩展。然后将结果视为目标类型的值。
    •   
    • 如果源类型与目标类型的大小相同,则源值将被视为目标类型的值。
    •   
  •   

答案 2 :(得分:4)

取决于;在checked上下文中,你会得到一个很大的例外;在unchecked上下文(默认值)中,您可以保留最后一个字节的数据,就像您一样:

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

答案 3 :(得分:3)

在您的特定情况下,当您查看值的位时,行为非常干净和干燥:

short myShort = 0x5D8C; // 23948
byte myByte = (byte)myShort; // myShort & 0xFF

Console.WriteLine("0x{0:X}", myByte); // 0x8C or 140

答案 4 :(得分:1)

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

答案 5 :(得分:1)

当您将整数类型转换为“较小”整数类型时,仅考虑较小的权重位。在数学上,就好像你使用了模运算一样。所以你得到的值是140,因为23948模数256是140。

将long转换为int将使用相同的机制。

答案 6 :(得分:1)

结果如下:

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

八位之上的所有东西都被丢弃了。 23948(0x5D8C)的低8位为140(0x8C)。

答案 7 :(得分:1)

嗯......因为当你把短(2个字节)转换成字节(1个字节)时,它只得到第一个字节,而23948的第一个字节代表140个。

答案 8 :(得分:1)

23948%256 = 140,转换后丢失了最重要的字节,因此输出为140

答案 9 :(得分:1)

就像你有一个两位数的数字“97”,然后将它转换为一位数字,你就失去了9而只保留了“7”