• ベストアンサー

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

chie65536の回答

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.4

追記。 当方の回答で 「リトルエディアン環境でコンパイル&実行するとビッグエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない関数」が「htonl関数そのもの」 と言いました。これは「送出時の観点」から書いた物です。 「受信時の観点」から書けば 「リトルエディアン環境でコンパイル&実行すると、ビッグエディアンからリトルエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない関数」が「ntohl関数そのもの」 となります(関数名が違う事に注意) つまり 「送出時は、htonl関数を呼んで送出する」 「受信時は、受信してからntohl関数を呼ぶ」 と言う事になります。 そういう訳で、htonl関数、ntohl関数とは「ネットワークバイトオーダーとローカルバイトオーダーを変換する関数のセット」と言う事になります。 そしてこれは「htonl関数、ntohl関数を呼んでさえおけば、実行するマシンが、リトルエディアンかビッグエディアンか気にする必要はない」と言う事を意味します。 この「実行するマシンが、リトルエディアンかビッグエディアンか気にする必要はない」と言うのが、ANo2の方が書いた >htonlを使った方が、簡単なはずです。 の「簡単」の意味です。

upanepa
質問者

お礼

分かりやすい説明ありがとうございます。 とても勉強になりました!

関連するQ&A

  • エンディアンについて

    すみません。 教えてください。 リトルエンディアンからビッグエンディアンに変換しないと いけません。 エンディアンについては勉強したつもりですが、 どうしてもわからないことがあります。 ご存知の方、教えていただせんか? 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バイト)などは 意識せず、そのままバイナリ出力しても、ビックエンディアンで出力されると いうことでよろしいでしょうか? そうなると、エンディアンってなんだんだ???と混乱しています。 わかりにくい説明で大変申し訳ござませんが、 よろしくお願いいたします。

  • ビックエンディアンで動作するPC

    バイトオーダでビックエンディアンとリトルエンディアンがあるのは知っていますが、 実際にビックエンディアンで動作するPCを見たことがありません。 (といいますかビックエンディアンで動作しているか分かりません) 秋葉原等でビックエンディアンで動作するPC(CPU・マザーボード)は買うことはできるのでしょうか? その場合のOS、Linuxになると思いますがディトリビューションどれがよいのでしょうか? クロスコンパイル環境に興味があり、エンディアンが違うPCでも動作するプログラムを 書いてみたいと興味があり質問させていただきました。

  • ftpでのネットワークバイトオーダーについて

    LinuxとUNIXのマシンでftpでファイルのやり取りをする場合、ftpのヘッダとデータ部分のネットワークバイトオーダーは、ビッグエンディアン or リトルエンディアンのどちらで行なっているのでしょうか? 参考になるURLや書籍等ありましたら教えて下さい。 TCP/IPは、ビッグエンディアンでヘッダ部分のやり取りを行なう。ということはネットでは見つかりましたが、ftpについては今の所、不明です。 申し訳ありませんが、どなたか教えて下さい。

  • インテル VS モトローラ

    こんにちは インテル系とモトローラー系でエンディアン(どちらかがリトル・どちらかがビック)が違うと言うことですが、 データのビットの並びが違うのですか? 例えば0番地のアドレスに1バイト(8ビット)のデータが入ってるとして リトルなら0x55 ビックなら0xAA ということでしょうか? またZ80、SHとかARMとかいっぱいCPUはありますが、これらはどちらの形式なんでしょうか? 比較表(比較表?)などあればお知らせ下さい

  • javaのエラーについて質問

    毎度、お世話になります。 下記のコードに於いて、コメント箇所でエラー(UnsupportedOperationException())が発生します。 Q1)このエラーの原因と、改良をご教授ください。 ============================= import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import java.util.Date; import java.util.Random; public class Main { public static void main(String[] args) { Random random = new Random(); random.setSeed((int) new Date().getTime()); ByteBuffer byteBuffer = ByteBuffer.allocate(10000 * 4); long start = System.currentTimeMillis(); ByteOrder order; ByteBuffer tmpBuffer; int[] ints; IntBuffer intBuffer; long end; // ビックエンディアン order = ByteOrder.BIG_ENDIAN; tmpBuffer = byteBuffer.order(order); ints = tmpBuffer.asIntBuffer().array(); //エラー発生:UnsupportedOperationException() intBuffer = IntBuffer.wrap(ints); System.out.println("ビックエンディアンで実行"); printChunk(random, ints, intBuffer); end = System.currentTimeMillis(); System.out.print("経過時間:"); System.out.println((end - start) + "msec\t"); // リトルエンディアン start = System.currentTimeMillis(); order = ByteOrder.LITTLE_ENDIAN; tmpBuffer = byteBuffer.order(order); ints = tmpBuffer.asIntBuffer().array(); //エラー発生:UnsupportedOperationException() intBuffer = IntBuffer.wrap(ints); System.out.println("リトルエンディアンで実行"); printChunk(random, ints, intBuffer); end = System.currentTimeMillis(); System.out.print("経過時間:"); System.out.println((end - start) + "msec\t"); } ========================================= 以上

    • ベストアンサー
    • Java
  • リトルエンディアン→ビッグエンディアン

    (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; 上記のようなリトルエンディアンの構造体の各メンバのデータを、ビッグエンディアンの構造体の各メンバのデータにそれぞれ格納するには どうしたらよいでしょうか?

  • リトルエンディアンというものでしょうか?使いづらいです。

    VC6で以下のようにメモリ上の4バイトは逆さなのでしょうか? 非常に使いづらいです。 正しく?1を取得する方法が知りたいです。 int a[2] = { 1, 2 }; _asm{ // 2003年頃の本を見ると__asmだし、他ではasmだった。 _asmはVC特有? mov esi, a // メモリ上では 0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00と逆さに入ってる mov eax, [esi+0]; // eaxが 0x10000000 // eaxには1が入って欲しいのですが無理なのでしょうか? 普通の感覚から考えてビックエンディアンが良いと思うのですが、 リトルエンディアンは何に便利なのでしょうか?

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

    現在、ワークステーション(SPARC+Soralis)上でFortranで書かれたプログラムがあります。 それをPC(x86+WindowsXP)の環境へ移行した所、Fortran記録(バイナリ)の内容が、CPUアーキテクチャの絡みでビックエンディアン/リトルエンディアンの問題が発生し、苦労しています。 Windows側で使用しているFortranコンパイラは「富士通 Fortran&C Packege V4.0」です。 PC側でまともにワークステーションのバイナリファイルを読みたいのです。 どなたか対策をご存じの方がいらっしゃいましたら、ぜひ、ご教授ください。 よろしくお願いいたします。

  • リトルエンディアン形式、ビッグエンディアン形式

    仕事上でリトルエンディアン形式、ビッグエンディアン形式を使う?のですが意味がまったく解りません 簡単に言ったら JPEGで容量:1.5M、サイズ:640x640、リトルエンディアン形式 JPEGで容量:1.5M以上、サイズ:639x639、ビッグエンディアン形式 となっています 何をどうすればイイのでしょうか? 初めてなので戸惑ってます ちなみにこの作業はコンテンツ作成です

  • 最近の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]; とすればいいでしょうか?