11

次のコードがあります。

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

ここでmyByte、値 23948 が含まれるとは思っていませんでした。255 が含まれると推測していました (1 バイトの最大値だと思います)。

しかし、これには 140 が含まれています。舞台裏で実際に何が起こっているのですか?

23948 が 1 バイトに収まらないという問題を解決する人を探しているわけではないことに注意してください。基本的な実装について疑問に思っているだけです。

4

10 に答える 10

15

Shortは2バイト型で、1バイトは1バイトです。2バイトから1バイトにキャストすると、システムに適切なものを強制し、元のバイトの1つ(最も重要なバイト)が削除され、データが失われます。23948(バイナリ:0101 1101 1000 1100)の値から残っているのは140で、これはバイナリでは10001100に変換されます。

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
        }   
    }
}
于 2011-09-27T21:07:15.560 に答える
6

基本的には最後の 8 ビットだけが必要ですが、一般的に、驚くべき動作を見つけた場合、次のステップは仕様を調べることです。セクション 6.2.1 から、この場合に関連する状況について、特に強調して説明します。

整数型から別の整数型への変換の場合、処理は、変換が行われるオーバーフロー チェック コンテキスト (§7.6.12) によって異なります。

  • チェックされたコンテキストでは、ソース オペランドの値が変換先の型の範囲内にある場合は変換が成功しますが、ソース オペランドの値が変換先の型の範囲外にある場合は System.OverflowException がスローされます。
  • チェックされていないコンテキストでは、変換は常に成功し、次のように進みます。
    • ソース タイプがデスティネーション タイプよりも大きい場合、ソース値は「余分な」最上位ビットを破棄することによって切り捨てられます。結果は、宛先タイプの値として扱われます。
    • ソースの型が宛先の型よりも小さい場合、ソースの値は、宛先の型と同じサイズになるように符号拡張またはゼロ拡張されます。ソース タイプが署名されている場合は、符号拡張が使用されます。ソース タイプが符号なしの場合は、ゼロ拡張が使用されます。結果は、宛先タイプの値として扱われます。
    • ソースの型が宛先の型と同じサイズの場合、ソースの値は宛先の型の値として扱われます。
于 2011-09-27T21:11:43.370 に答える
4

場合によります; コンテキストではchecked、大きな脂肪例外が発生します。コンテキスト (デフォルト) では、unchecked次の場合と同じように、最後のバイトからデータを保持できます。

byte b = (byte)(value & 255);
于 2011-09-27T21:12:01.973 に答える
3

特定のケースでは、値のビットを見ると、動作はかなりカットされています。

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

Console.WriteLine("0x{0:X}", myByte); // 0x8C or 140
于 2011-09-27T21:08:51.847 に答える
1

最後の8ビットのみが保持されます。バイナリの23948は101110110001100bです。その最後の8ビットは10001100bで、これは140に相当します。

于 2011-09-27T21:08:47.607 に答える
1

整数型を「より小さい」整数型にキャストすると、重みの小さいビットのみが考慮されます。数学的には、モジュロ演算を使用したかのようです。23948 modulo 256 は 140 であるため、値は 140 になります。

long を int にキャストするには、同じメカニズムを使用します。

于 2011-09-27T21:08:53.517 に答える
1

次のようにしても、結果は同じです。

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

8 ビットより上のものはすべて単純に破棄されます。23948 (0x5D8C) の下位 8 ビットは 140 (0x8C) です。

于 2011-09-27T21:09:17.640 に答える
1

ええと... short (2 バイト) を byte (1 バイト) にキャストすると、最初のバイトのみが取得され、23948 の最初のバイトは 140 を表すためです。

于 2011-09-27T21:09:54.983 に答える
1

23948 % 256 = 140、変換後に最上位バイトが失われたため、出力は 140

于 2011-09-27T21:10:12.377 に答える
1

2 桁の数字「97」を 1 桁の数字に変換すると、9 が失われ、「7」だけが残るようなものです。

于 2011-09-27T21:10:20.667 に答える