• ベストアンサー

エンディアン:2バイトのデータをShort intにしたいのですが?

1.Intelの CPU リトルエンディアンでの、問題です。 バイナリファイルをバイト単位で読込み、これを16ビットの整数にしたいのですが、以下のようにコーディングしましたが、うまくいきません。解決方法をご教示下さい。 char s[2]; short int x;   // 16ビットの整数です // s[0] s[1]に、データを読み込みます。 x = (short)(s[0] + 256 * s[1]); 2.同様の問題で、ビッグエンディアンの場合は、どうすればよいかも、ご教示下さい。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

char s[2]; short int x; // s[0], s[1]にデータを読み込む x = (short)((s[0] & 0xff) | ((s1[1] << 8) & 0xff00)); でどうでしょうか? これはCPUがビッグエンディアンの場合でも同じです。 ファイルへの格納形式がビッグエンディアンの場合、CPUがリトルエンディアンかビッグエンディアンかに関わらず、 x = (short)((s[1] & 0xff) | ((s1[0] << 8) & 0xff00)); とすればよいと思います。

ccppmaster
質問者

お礼

ありがとうございました。 無事、解決いたしました。 ビットシフトを自分なりに考えてやってみていたのですが、単純に足し算したりしてうまくいかなかったので、:-) まだ、疑問に思っていることがたくさんありますので、よろしくお願いします。 ありがとうございました。

その他の回答 (2)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

整数演算でもともめるんだったらcharではなくunsigned charにしないと。 最上位ビットがたってたらマイナスになっちゃいます。 シフト演算するんだったらcharでもかまいませんが。

ccppmaster
質問者

お礼

アドバイスありがとうございます。 まだ、疑問に思っていることがありますので、またよろしくお願いします。

  • keroro001
  • ベストアンサー率23% (71/304)
回答No.1

x = (short)s[0] + 256 * (short)s[1]; これでいかんですか?

ccppmaster
質問者

お礼

ご回答ありがとうございます。 試しているデータが悪かったようで、他の方の回答により、この式のままでも良いことが確認出来ました。 ありがとうございました。

関連するQ&A

  • 最近のCPUのほとんどはリトルエンディアンかビッグエンディアンでしょうか?

    2000年あたり以降に出た Windows, Mac, Linuxに使われているCPUのほとんどはリトルエンディアンかビッグエンディアンでしょうか? また、たとえば以下のような方法でエンディアンを調べられると考えていいのでしょうか?(VC++です) #include <windows.h> void GetEndian4(char* c){ unsigned __int32 a=0x03020100; BYTE *b = (BYTE*)&a, i=4; while (i--) c[i]=b[i]; } ////////// const char e[4]={}; GetEndian4( const_cast<char*>(e) ); //eが 0,1,2,3 になればリトルエンディアン //3,2,1,0 になればビッグエンディアン //PDP-エンディアンだと 2,3,0,1 …のはず (または2択ならこれだけでも判断可能…?) short s=1; printf( *(char*)&s ? "リトルエディアン\n" : "ビッグエディアン\n" ); あとここでもアラインメントの問題が絡みますが、このように アラインメントが(2のべき乗だとして)大きいであろう方から小さいであろう方にキャストする分には安全で、逆に sizeof(short) == sizeof(char)*2 として char c[2]={1,0}; short s=*(short*)&c; というのは危険な場合がある、ということでしょうか? また、その場合は たとえばビッグエンディアンなら short s=(c[0]<<8)|c[1]; とすればいいでしょうか?

  • リトルエンディアン→ビッグエンディアン

    (1)リトルエンディアン typedef struct recvData{  int a;  unsigned char b[16]; unsigned char c[8]; unsigned int d[4]; } recvData_t; recvData_t rData; (2)ビッグエンディアン typedef struct sendData{  int a;  unsigned int b[4]; unsigned int c[2]; unsigned int d[4]; } sendData_t; sendData_t sData; 上記のようなリトルエンディアンの構造体の各メンバのデータを、ビッグエンディアンの構造体の各メンバのデータにそれぞれ格納するには どうしたらよいでしょうか?

  • エンディアンについて

    すみません。 教えてください。 リトルエンディアンからビッグエンディアンに変換しないと いけません。 エンディアンについては勉強したつもりですが、 どうしてもわからないことがあります。 ご存知の方、教えていただせんか? CPUはリトルです。 まず、エンディアンの違いについては 以下のように認識しています。 x = 0xAABBCCDD メモリの配置方法が、 トリルだと DD CC BB AA ビックだと AA BB CC DD だと思っています。32ビットの場合です。 で、これを変換するには、htonlで変換可能だと思っっています。 (試したところ可能でした) で次に、32ビットを超えるデータ、たとえば100バイトとかを mallocにして変数に代入しました。 この時はエンディアン変換(ファイルに出力する際)は必要ないのでしょうか? 試しに出力すると、 x = 0x AA BB CC DD EE FF GG ・・・・・・ZZ (100バイトと仮定) バイナリでの出力結果は AA BB CC DD EE FF GG ・・・・・となっていました。 私の認識だと、本CPUはリトルエンディアンのため、 ZZ ・・・・・・・・ DD CC BB AA (四バイトずつ反転しているデータ) が出力されるものと思っていました。(反転してメモリに格納されるため) リトル/ビックを意識しないといけないのは、 2バイトや4バイトの時のみで、それを超える大きなデータ(100バイト)などは 意識せず、そのままバイナリ出力しても、ビックエンディアンで出力されると いうことでよろしいでしょうか? そうなると、エンディアンってなんだんだ???と混乱しています。 わかりにくい説明で大変申し訳ござませんが、 よろしくお願いいたします。

  • バイナリデータからの値の取得について教えてください

    今、バイナリデータから値を取りだそうとがんばっています。 しかし、うまくいかずに困っています。 困っていることは2点あります。 (1)バイナリデータにはリトルエンディアンで格納していると書いています。 まず、リトルエンディアンで書かれている場合、どのような処理を考えることが必要なのでしょうか? (2)バイナリデータには、 はじめに文字列(char)型4バイトで「RIFF]という値 次に32ビット符号なし整数で4バイトの数字、 次に4052バイトの構造体 などと収納されているようです。 このように入っているデータから値を取得するにはどのようにしたらよいのでしょうか? 全然できなくて困っています。 教えていただけないでしょうか? よろしくお願いいたします。

  • Endianについて パート2

    elttacさん、Tacosanさん、terrar5さん、先日はありがとうございました。どうしても、疑問でならない部分がありまして、よろしければ、もう少しお付き合いよろしくお願い致します。 /--------------------------------------------------------------------------- エディアンとは、2 バイト以上の数値データを記録・転送するときの 「各バイトの並べ方」です。 たとえば,2 バイトの数値 0x0102(10 進数で 258)を考えましょう。ビッグエンディアンでは,この格納順は正順,つまり,   01 02 になります。 -------------------------------------------------------------------------------/ 1バイト目の0x02(2進数で 0000,0002)ですが、これも並び順によっては、0x20になっちゃったりしないのでしょうか? 1バイトでもビット単位で並び順が違えばさかさまになるような気がしまして。(1台のPC上では、バイト単位で処理しているので、大丈夫!? ネットワークでは、1bit単位でデータが転送されていますので???) ビット単位でもビッグエンディアンやリトルエンディアンみたいなのがあるのでしょうか?

  • エンディアンの問題

    バイナリファイルの記憶の仕方にビッグエンディアンとリトルエンディアンがあります。たとえば16ビットのうちの前半の8ビットと後半の8ビットが逆になっていることだと思います。そこで質問ですが、 ○なぜ、そういう風に分かれているのか。 ○この問題が顕在化するのはどのような場合か。 ○その解決方法は? という点について教えて頂きたいのですが。私の記憶では例えばUnixとDOS(Windows)で逆である(どちらがどちらなのか分かりませんが)ということでした。もし、そのことが問題であれば、解決法としてはとにかく反転すればよいということになるかもしれません。簡易ソフトなどもあるようですし、自分でプログラムを書いたこともあります。もちろんどちらが本当に正しいのか判別できなければなりませんが。

  • リトルエンディアンの1byteデータのビット割付

    リトルエンディアン方式と聞くと2byteデータだったら上位下位が逆転して メモリに割りついているって認識なんですけども、ビット割付も逆転している認識 で問題ないでしょうか? 例えば、1byteの0x1Fというデータがリトルエンディアン方式のビット割付だった場合 1111 0001という割付になるのでしょうか?

  • リトルエンディアン、ビッグエンディアンについて

    リトルエンディアン、ビッグエンディアンについて 質問があります。 (1)簡単にそのPCがリトルエンディアンなのか、ビッグエンディアン  なのか、分かる方法はありますか?  簡単なCプログラムを書いてメモリ状態をダンプするのが、  一番早いのでしょうか?  それとも、Intel系?モントローラ系?CPUにはあまり詳しくないので、  分かりませんが、これらのどちらかに属していれば決められるので  しょうか?ほかの系とかあるのかな・・・ (2)ネットワークプログラミングをするときに、ビッグエンディアンの  マシンからデータを送出する場合には、htonlなどの関数を使用しなく  ても問題ありませんでしょうか?(ネットワークバイトオーダが  ビックエンディアンであるため)

  • intやshortやcharの変数確保時間

    for文などでよく一時変数に for ( int i=0; ・・・ とか for ( short s=0; ・・・ とか for ( char i=0; ・・・ みたいに整数型の変数が使われます。 確か変数の表せる範囲は long>int>short>char だったと思うのですが、変数を確保する時間やメモリサイズに違いはあるのでしょうか? たとえばlong型変数を10万個確保する時間とintとかshortとかcharのそれ とは違いがあるのかなぁと疑問に思いました。

  • ビッグエンディアンをPCで処理する問題

    ビッグエンディアンと指定されているバイナリファイルがあります。 これをPC(intel系,Linux or Windows)で処理する場合、エンディアンの変換が必要だろうと思います。具体的にはどのようにするのでしょうか。ネットでもダウンロードできそうですが。 変換コマンド -btol ファイル名(ビッグ)> ファイル名(リトル) という感じですかね。こんなものあるでしょうか。 購入したバイナリファイルなのですが、このご時勢たいていPCで処理するわけでしょうからリトルであってほしいものだと思いますが。 ところでMACはビッグとリトルのどっちなのでしょうか。