質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.26%

  • C#

    4999questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

byte[] intの変換で、いろいろ疑問

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 222

nomurax

score 13

前提・実現したいこと

こんにちは。いつもたいへんお世話になります。
byte[] intの変換で、コンソールアプリケーションを作っていろいろ試しています。
そこでいろいろ疑問が出てきました。

            byte[] bytes = { 5, 12, 24, 40, 58 };
            var size = 16777216 * bytes[0] + 65536 * bytes[1] + 256 * bytes[2] + bytes[3];//Q1
            Console.WriteLine("convert1600 size="+size);

            byte[] size1 = BitConverter.GetBytes(size / 16777216);//Q2, Q3
            byte[] size2 = BitConverter.GetBytes(size % 16777216 / 65536);
            byte[] size3 = BitConverter.GetBytes(size % 16777216 % 65536 / 256);
            byte[] size4 = BitConverter.GetBytes(size % 16777216 % 65536 % 256);


            List<byte> afterbytes = new List<byte>();
            afterbytes.AddRange(size1);
            afterbytes.AddRange(size2);
            afterbytes.AddRange(size3);
            afterbytes.AddRange(size4);

            List<byte> afterbytes2 = new List<byte>();
            afterbytes2.Add(size1[0]);
            afterbytes2.Add(size2[0]);
            afterbytes2.Add(size3[0]);
            afterbytes2.Add(size4[0]);

            var sizebyte1 = size / 16777216;
            var sizebyte2= size % 16777216 / 65536;
            var sizebyte3= size % 16777216 % 65536 / 256;
            var sizebyte4= size % 16777216 % 65536 % 256;

            List<byte> afterbytes3 = new List<byte>();
            //afterbytes3.Add(sizebyte1);//Q4
            //afterbytes3.Add(sizebyte2);
            //afterbytes3.Add(sizebyte3);
            //afterbytes3.Add(sizebyte4);

            byte[] bytesarray = bytes.ToArray();
            int bitconvertersize32 = BitConverter.ToInt32(bytesarray, 0);
            Console.WriteLine("int bitconvertersize=" + bitconvertersize32);
            byte[] bytesbybitconverter1 = BitConverter.GetBytes(bitconvertersize32);//Q5, Q6,Q7

            byte[] bytesbybitconverter = BitConverter.GetBytes(size);

発生している問題/疑問

Q1)16777216や65536や256はどこから出てきたのか?
Q2)intをGetBytesすると、なぜ4つずつの組の配列になるのか?
Q3)組の配列の[1],[2],[3]は0,0,0だがつねに0なのか?
Q4)List<byte>にintをAddできないが、intをbyteに変更する方法は? BitConverterを使う?
Q5)BitConverter.GetBytesを使うと16777216や65536や256はどこに消えるのか?
Q6)ひょっとしてbytesはつねに4つの組の配列であり、16777216や65536や256がデフォルトなのか?
Q7)戻すと配列は、{5,12,24,40}となるが58はどこに消えたのか?
4つずつなら次のようにすればどうかと思ったが、これでも後半の58,63,71.86はなくなる。
List<byte> bytes = new List<byte>({5,12,24,40,58,63,71,86});

お知恵拝借したいです。

補足情報(言語/FW/ツール等のバージョンなど)

Windows10 Home 1709 64bit

Microsoft Visual Studio Community 2017
Version 15.1 (26403.3) Release
VisualStudio.15.Release/15.1.0+26403.3
Microsoft .NET Framework
Version 4.7.02556

インストールされているバージョン:Community
Visual C# 2017   00369-60000-00001-AA631

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ozwk

    2017/12/13 14:19

    コードは‘‘‘ ではなく```(日本語キーボードならShift+@)で囲ってください

    キャンセル

  • aglkjggg

    2017/12/13 15:15 編集

    変数型やエンディアン、2進数16進数n進数について勉強した方がいいと思います。原理を知らなければ永遠に解決しない問題です。また、過去にも似た質問をしていて今回の質問はその続きかと思うのですが何故新しい質問として作ったのでしょうか…?

    キャンセル

回答 3

checkベストアンサー

+3

Q1)16777216や65536や256はどこから出てきたのか?

16777216 = 0x1000000  = 0x100 * 0x100 * 0x100
65536    = 0x10000    = 0x100 * 0x100
256      = 0x100

10進数: 12と34を入力して1234を出力する時は12 * 100 + 34 * 1
16進数: 0xABと0xCDを入力して0xABCDを出力する時も同様に0xAB * 0x100 + 0xCD * 1

Q2)intをGetBytesすると、なぜ4つずつの組の配列になるのか?

C#のintが32bit = 4byteだから

Q3)組の配列の[1],[2],[3]は0,0,0だがつねに0なのか?

1byte分の入力しか入れてないから

byte[] size1 = BitConverter.GetBytes(size / 16777216);
byte[] size2 = BitConverter.GetBytes(size % 16777216 / 65536);
byte[] size3 = BitConverter.GetBytes(size % 16777216 % 65536 / 256);
byte[] size4 = BitConverter.GetBytes(size % 16777216 % 65536 % 256);

32bitの変数sizeに対して0x1000000で割ると、出て来る数は-128~+127

size % 16777216 これは上位8bitを削って下位24bitを出してるのでそこから2の16乗で割ると出て来る数は-128~+127
以下同様

削ぎ落とさずに

byte[] le_size = BitConverter.GetBytes(size);

でよい

Q4)List<byte>にintをAddできないが、intをbyteに変更する方法は? BitConverterを使う?

BitConverterでもキャストでもお好きにどうぞ

Q5)BitConverter.GetBytesを使うと16777216や65536や256はどこに消えるのか?

12345 という十進数は 1 * 10000 + 2 * 1000 + 3 * 100 + 4 * 10 + 5 * 1で表せる
12345 から 1,2,3,4,5を取り出す過程で10のn乗は使われている
(2のn乗進数の場合bitシフトでやるけどね)

Q6)ひょっとしてbytesはつねに4つの組の配列であり、16777216や65536や256がデフォルトなのか?

後半意味わかんないけど、ハードコーディングされてるという意味ではYES
bytesは常に4つの組 intに変換してる以上YES

Q7)戻すと配列は、{5,12,24,40}となるが58はどこに消えたのか?

intが32bitなので消えました

List<byte> bytes = new List<byte>({5,12,24,40,58,63,71,86});
としたとき、
ひょっとして、それは、
List<List<byte>> bytess = new List<List<byte>>({{5,12,24,40}, {58,63,71,86}});
みたいに

4byte毎にintに変換したいのかバイト列の一部をintに変換したいのか
見失ってませんか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/13 15:17

    ありがとうございます。
    Q1-1)お伺いしたかったのは、2の乗数には、2^4の16や2^15の32000とかもあると思うのですが、なぜ256と65536と16777216だけなのでしょうか?
    Q3)1byteを越える入力を入れるにはどんな値にすればよいのですか?
    Q6、7)で、
    List<byte> bytes = new List<byte>({5,12,24,40,58,63,71,86});
    としたとき、
    ひょっとして、それは、
    List<List<byte>> bytess = new List<List<byte>>({{5,12,24,40}, {58,63,71,86}});
    みたいに書く、ってことでしょうか?
    List<List<byte>> bytess = new List<List<byte>>();
    List<byte> bytes1 = new List<byte>({5,12,24,40});
    List<byte> bytes2 = new List<byte>({58,63,71,86});
    bytess.Add(bytes1);
    bytess.Add(bytes2);
    というような。

    キャンセル

  • 2017/12/13 18:23

    ありがとうございます。
    4byteごとにintに変換するのと、バイト列の一部をintに変換するのとでは違うのですか?
    やりたいのは、byte[] → int → byte[]で、もとの値に戻すこことです。
    現在は、元に戻すと58が消えてしまうので困っています。
    消えない方法を知りたいです。

    キャンセル

  • 2017/12/13 18:41

    > 4byteごとにintに変換するのと、バイト列の一部をintに変換するのとでは違うのですか?
    似て非なる問題です。

    > やりたいのは、byte[] → int → byte[]で、もとの値に戻すこことです。
    intには4バイトまでしか入らないので
    5バイト以上は無理です。

    byte[] → int[] + バイト列の長さ情報 → byte[]
    もしくは元のバイト列の長さが4の倍数であるという前提がある事で
    byte[] → int[] → byte[]
    が可能です

    キャンセル

  • 2017/12/13 19:51

    纏めて一言でいうなら
    (Memory/File)Stream +
    BinaryReader+IPAddress.NetworkToHostOrder
    BinaryWriter+IPAddress.HostToNetworkOrder
    使っとけ
    https://wandbox.org/permlink/tvuDqssFMSAeLvF3

    キャンセル

  • 2017/12/16 18:52

    はい。ほしいのは、
    byte[] → int[] + バイト列の長さ情報 → byte[]
    もしくは元のバイト列の長さが4の倍数であるという前提があるうえで
    byte[] → int[] → byte[]
    であることに気づきました。
    ありがとうございます。

    キャンセル

0

Q1)16777216や65536や256はどこから出てきたのか?
Q3)組の配列の[1],[2],[3]は0,0,0だがつねに0なのか?

2の8乗(1byteで表せる数の限界+1)、
2の16乗(2byteで表せる数の限界+1)、
2の24乗(3byteで表せる数の限界+1)

Q2)intをGetBytesすると、なぜ4つずつの組の配列になるのか?

C#のintは32bit(=4byte)符号付き整数だから

Q4)List<byte>にintをAddできないが、intをbyteに変更する方法は? BitConverterを使う?

intのバイト配列表現をList<byte>にAddしたいならそう。

Q5)BitConverter.GetBytesを使うと16777216や65536や256はどこに消えるのか?

消えるも何も使ってない。

byte[] bytes = { 5, 12, 24, 40, 58 };
// 中略
byte[] bytesarray = bytes.ToArray();
int bitconvertersize32 = BitConverter.ToInt32(bytesarray, 0);
// 中略
byte[] bytesbybitconverter1 = BitConverter.GetBytes(bitconvertersize32);//Q5,

Q6)ひょっとしてbytesはつねに4つの組の配列であり、16777216や65536や256がデフォルトなのか?

何をbyte列表現に変換するかによる。

Q7)戻すと配列は、{5,12,24,40}となるが58はどこに消えたのか? 

消えるも何も使ってない。

byte[] bytes = { 5, 12, 24, 40, 58 };
// 中略

int bitconvertersize32 = BitConverter.ToInt32(bytesarray, 0); // intは4byteだから[0]~[3]までしか使われない

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

疑問の数々はともかく int は 4 バイトなので 5 バイトの情報を収めることはできません。
long を使ってください。

バイト列と long の相互変換についてはこちら
方法: バイト配列を int に変換する (C# プログラミング ガイド)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.26%

関連した質問

同じタグがついた質問を見る

  • C#

    4999questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。