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

No.5ベストアンサー
- 回答日時:
C言語で説明しますが、特にC言語を知らなくとも大丈夫だと思います。
まず、C言語では
char 1byte整数
short 2byte整数
long 4byte整数
と決まっています。
この場合
char c = 0x12;
これに関しては、ビッグエンディアンもリトルエンディアンも関係ありません。
ですから、
char cs[100];
と言うのも、同様にビッグエンディアンもリトルエンディアンも関係ありません。
たぶん、質問者さんが言われている100バイトのデータがこれに該当すると思います。
そして問題なのは、
short s = 0x1234;
long l = 0x12345678;
など、2バイト以上の型の並び順です。
リトルエンディアンで言えば
s を1バイト単位で見た場合、c[0]=0x34,c[1]=0x12となります。
l を1バイト単位で見た場合、c[0]=0x87,c[1]=0x65,c[2]=0x43,c[3]=0x21となります。
逆にビッグエンディアンの場合は
s を1バイト単位で見た場合、c[0]=0x12,c[1]=0x34となります。
l を1バイト単位で見た場合、c[0]=0x12,c[1]=0x34,c[2]=0x56,c[3]=0x78となります。
10進数で、たとえてるなら「一、十、百、千」と4桁の10進数があった場合
リトルエンディアンだと並びが、「一、十、百、千」
ビッグエンディアンだと並びが、「千、百、十、一」
になると言うもので、つまり並びの重みの向きが違うと言うものです。
アドレス(番地)は、1バイトごとに付けられます。
つまり、
char a[4];とあり、もしa[0]が0番地とした場合、
a[4]は3番地となります。
そして、4バイト整数は連続した4つの番地を使う訳ですが、この場合の0番地が大きい位なのか、小さい位なのかでビッグエンディアン/リトルエンディアンと呼ばれるようになります。
また、最近では8バイト(64bit)も普通に扱えるようになりましたが、これも考えは同じです。
そして、雑学的なことを書けば、リトルエンディアンのメリットは、たとえばlongで定義したエリアの中身が実際には0か1しか値が入らないと言うケースはしばしば発生します。
それをもし、何か間違ってcharで参照したとしても、それは正確に0か1が参照できるのです。(つまり1バイトに収まる値ならば正しく参照可能)
昔は、このようなことをメモリが少なかったため裏技的にやる人もいましたが、もちろん今ではトラブル以外の何ものでもないため、絶対にやりません。
No.7
- 回答日時:
もはや余談の範疇ですが, 世の中には「PDP エンディアン」のような奴もいるので一筋縄ではいかなかったりします. なんか, もっと変態ちっくなやつもあるみたいだけど.
で実行時に「どうしてもエンディアンを知りたい」と思ったら
#include <limits.h>
union FindLongEndian {
unsigned long lval;
unsigned char byteorder[sizeof (unsigned long)];
} x;
x.lval = 0;
for (unsigned int i = 1; i <= sizeof (unsigned long); ++i) {
x.lval = (x.lval << CHAR_BIT) + i;
}
とすれば x.byteorder[] に入ってくれる... かな?
ところで「char が 1バイト, short が 2バイト, long が 4バイト」に決まってる言語が想像つかないんだけど, 何かあったっけ?
No.6
- 回答日時:
私が普段使っている、MacOSX(64bitカーネル)のgccでは、sizeof(long)==8 なのですが...
<「longは4バイトと決まっている」
さて。
同じmallocでも、
char *buff = malloc(100) ;
short * s = (short *) buff ;
として
s[0]=0x1234 ;
とすると、
buff[0]==0x34 ;
buff[1]==0x12 ;
となります(sizeof(short)==2,リトルエンディアンの場合)
これがビッグエンディアンだと
buff[0]==0x12 ;
buff[1]==0x34 ;
となります。
・buff[0],buff[1]のchar2つが、s[0]のshort一つになる:これがcharが100個か、2個の塊(short)が50個か、ということ。
・そのどちらに上位が入るか、がエンディアン
マス目に書いてみたり、Excelみたいな表に書いてみたりすると、イメージしやすいかもしれません
No.3
- 回答日時:
「4Byteデータ25個のカタマリ」だとすると (4バイトごとに格納されるので)
DD CC BB AA HH GG FF EE ...
のような気がしますが>#2.
No.2
- 回答日時:
ケースバイケース、としか言いようがありません。
質問のケースでは、「100Byteのデータ」というのが所詮「1Byteデータ100個のカタマリ」でしかないためです。
これが「4Byteデータ25個のカタマリ」であればあなたの想定通りの結果になります。
この回答への補足
ご回答ありがとうございます。
Tacosanさんに追加で質問を書いて登校してから
あっ思いました。結論は以下ということですよね。
間違っていたら、ご指摘ください。
-----------------
質問のケースでは、「100Byteのデータ」というのが所詮「1Byteデータ100個のカタマリ」でしかないためです。
これが「4Byteデータ25個のカタマリ」であればあなたの想定通りの結果になります。
-----------------
なので、
long int の場合は4バイト確保されているので、
メモリ上には逆に入る。
char *buff に
いくらmalloc(1000)をしたところで、
それは1バイトのデータが1000ということなので、
反転されない。(1バイトはそのままメモリに格納されるから)
ということですよね?
まさに、
---------------------------------
「100Byteのデータ」というのが所詮「1Byteデータ100個のカタマリ」でしかないためです。
---------------------------------
ということですね。
少しエンディアンについて理解できた気がします。
No.1
- 回答日時:
「htonl でビッグエンディアンに変換できる」というのは正しいといえば正しいんだけど, より正確には
ホストのバイトオーダーからネットワークバイトオーダーに変換する
です. もちろん「ネットワークバイトオーダー」は「ビッグエンディアン」なので, リトルエンディアンのホストで実行すれば結果的に「リトルエンディアンからビッグエンディアンに変換できる」ということにはなります.
後の例は
・「32ビットを超えるデータ、たとえば100バイトとかをmallocにして変数に代入しました。」というのがどのように入れているのかが分からん
・「バイナリでの出力」はどのようにしているのか不明
など, ここには書かれていないことがいくつかあるのでなんとも言えません.
具体的に「こんなコードでこうやったんだけど....」というのが出てくれば言いようもある.
この回答への補足
みなさん、ご回答ありがとうございます。
説明不足で申し訳ないです。
>・「32ビットを超えるデータ、たとえば100バイトとかをmallocにして変数に代入しました。」
>というのがどのように入れているのかが分からん
ですが、
a[] = {"AA","BB","CC"・・・・・ZZ}(100バイト)
char *buff;
buff = malooc(100);
memcoy(buff, a, 100)
として代入しています。
>・「バイナリでの出力」はどのようにしているのか不明
は、
"wb" で開いたfpに、
fwrite(buff, 1, 100, fp)
としています。
この時、ファイルには、
AABBCCDD・・・・・ZZと出力されています。
ZZ・・・・・BBAA とは出力されていません。
リトルエンディアンなのに、そのまま出力されている現象が
理解できていません。
ちなみに
int32 a = 0xAABBCCDD;
とすると、DDCCBBAAと出力されています。
以上、よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) マクロを教えてください。 7 2023/06/01 19:47
- その他(プログラミング・Web制作) プログラミング python pandas 固定長データの出力 2 2022/08/16 11:22
- Visual Basic(VBA) vba 等間隔の列に対しての計算 6 2022/05/17 20:15
- Excel(エクセル) エクセルデーターの並び替え 5 2022/08/06 09:59
- Excel(エクセル) 【vba】日付の形式が勝手に変わってしまう。 1 2022/09/29 10:54
- その他(趣味・アウトドア・車) 12V/5V DCDCコンバーターについて 4 2023/06/20 07:08
- 自転車修理・メンテナンス クロスバイククランクについて 2009年式ルイガノRSR4に乗っています。 あろう事がクランクが折れ 2 2022/11/17 12:59
- Excel(エクセル) エクセルでセルに何らかの文字が入力されたらそれを任意の数値として認識させる方法がしりたいです。 3 2023/03/16 20:19
- 車検・修理・メンテナンス 2代目フィットに乗っていますが ハブベアリングについて教えてください 燃費にも関係ある? 3 2023/08/25 11:04
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
1Mバイトって何バイト?
-
ICカードデータサイズ比較
-
携帯電話の略語であるMBって英...
-
1メガ、1ギガはナンバイトですか?
-
EXCELでの16進数取り出し、上...
-
実行計画の「COST」と「BYTE」...
-
5000KBytes/sをbitに変換するには
-
IBM漢字とUTF-8の変換について
-
KBのMB違いって
-
K KB MB について詳し...
-
メモリーの単位を解説してくだ...
-
単位の違いを教えてください。
-
oracle11gで、PL/SQLにてAとい...
-
GB.KB.MBとは?
-
1バイトは何ビット?
-
1MBは?
-
KBとMB
-
EXCELのワークシートの大きさ
-
Stirlingについて
-
24ビットのメモリー容量の求め...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
EXCELでの16進数取り出し、上...
-
携帯電話の略語であるMBって英...
-
文字の容量(サイズ)についての...
-
実行計画の「COST」と「BYTE」...
-
アルファベット30文字は何バイ...
-
KBのMB違いって
-
CSV データのバイト数を調べる...
-
GB と Gbの違いの意味
-
1Mバイトって何バイト?
-
KBとMB
-
Excel_VBAで改行コードの無いフ...
-
Pingについてご教授ください。
-
おねがいします。
-
K KB MB について詳し...
-
32bit = 4GB(バイト)?
-
Oracle AL32UTF8でのバイトサイ...
-
2バイト文字を一括削除するマクロ
-
16進数どうしの乗算
-
5000KBytes/sをbitに変換するには
-
byte、KB、MB の単位の変換につ...
おすすめ情報