none
C#で2つのshort型(2byte)をint型(4byte)に、またその逆を行うには RRS feed

  • 質問

  • いつもお世話になっております。

    C#でint型(4byte)の数値を2バイトずつ(short型)、上位16bit(2バイト)・下位16bit(2バイト)に分けたいです。

    調べたところ、ビット演算が妥当のようですが、いまいちよくわかっていません。

    また、上記の逆変換で、2つのshort型(2byte)をint型(4byte)に変換も行いたいです。

    良い方法をご存じの方がいらっしゃいましたらご教授お願い致します。

    2020年7月8日 14:18

回答

  • 算術演算を使うと、負数が含まれるときに不正になりがちですね。

    全てビット演算で行う方が良いでしょう。

    short upper = (short)(x >> 16); short lower = (short)(x & 0xffff); int remem = (upper << 16) | (lower & 0xffff);

    • 回答としてマーク coco2014 2020年7月9日 0:30
    2020年7月9日 0:11

すべての返信

  • このような形になると思いますがいかがでしょうか。
    (分かりやすくするため2進数リテラルで記載しています)
    int origin = 0b_0000_0000_0000_0011_0000_0000_0000_1100; // 131072 + 65536 + 8 + 4
    System.Console.WriteLine(origin); // 196620
    
    // 16 bit 分を右へシフトさせて 0b_0000_0000_0000_0011 を作る
    short upper = (short)(origin >> 16);
    System.Console.WriteLine(upper); // 3
    
    // マスクで下位 16 bit 分のみ取り出し 0b_0000_0000_0000_1100 を作る
    short lower = (short)(origin & 0b_1111_1111_1111_1111);
    System.Console.WriteLine(lower); // 12
    
    // 戻す場合
    int restored = (upper << 16) + lower;
    System.Console.WriteLine(restored); // 196620

    • 回答としてマーク coco2014 2020年7月9日 0:28
    • 回答としてマークされていない coco2014 2020年7月9日 0:28
    2020年7月8日 15:33
  • こんな書き方もありかと。

    // 65536 = 0x00010000
    short su, sl; int iorig; su = (short)(iorig / 65536); sl = (short)(iorig % 65536); iorig = su * 65536 + sl
    2020年7月8日 21:30
  • 算術演算を使うと、負数が含まれるときに不正になりがちですね。

    全てビット演算で行う方が良いでしょう。

    short upper = (short)(x >> 16); short lower = (short)(x & 0xffff); int remem = (upper << 16) | (lower & 0xffff);

    • 回答としてマーク coco2014 2020年7月9日 0:30
    2020年7月9日 0:11
  • skazukiさん

    他のページで説明があったのですが、何をやっているのかわからなくて困ってました。

    skazukiさんの説明で理解できました。

    わかりやすい説明ありがとうございます。

    参考にさせていただきます。

    ありがとうございました!


    2020年7月9日 0:23
  • 外池さん

    回答ありがとうございます。

    簡単に記載ができてよさそうですね。

    何をやっているかを理解して、理解でいたらこちらを使わせていただこうと思います。

    ありがとうございます。

    2020年7月9日 0:25
  • Hongiangさん

    回答ありがとうございます。

    なるほど!負数が含まれると不正になりがちなんですね。

    ビット演算が妥当ということですね。

    こちらの方法でいかせていただきます!

    ありがとうございました。

    2020年7月9日 0:30
  • Hongliangさんがご指摘されてますが、小生の記述はダメですね(恥) 負数の場合「おかしくなりがち」ではなくて、全面的におかしくなります。

    小生の記述が正しく働くのは、intとshortの変換で、正の数のとき。あるいは、uintとushortの間の変換に限ります。

    2020年7月9日 8:54