すみません。
教えてください。
リトルエンディアンからビッグエンディアンに変換しないと
いけません。
エンディアンについては勉強したつもりですが、
どうしてもわからないことがあります。
ご存知の方、教えていただせんか?
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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
KBのMB違いって
-
文字の容量(サイズ)についての...
-
KBとMB
-
EXCELでの16進数取り出し、上...
-
1Mbpsって毎秒何キロバイト?
-
ffftpのサイズの単位は何でしょ...
-
マトリックスサイズが512×512で...
-
K KB MB について詳し...
-
1KBは、2の8乗X1000ではない...
-
実行計画の「COST」と「BYTE」...
-
速さって?
-
1Mバイトって何バイト?
-
こちらの商品をpcにてexFATにて...
-
ACCESS97での全角日本語の判定...
-
動画容量10Gを50Mpdsでアップロ...
-
携帯電話の略語であるMBって英...
-
KとKB
-
文字数5000字、文字コードが2バ...
-
HDDの容量が320Gなのに298Gしか...
-
何Mバイトになりますか?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
文字の容量(サイズ)についての...
-
携帯電話の略語であるMBって英...
-
KBのMB違いって
-
EXCELでの16進数取り出し、上...
-
KBとMB
-
1Mバイトって何バイト?
-
K KB MB について詳し...
-
CSV データのバイト数を調べる...
-
Excel_VBAで改行コードの無いフ...
-
実行計画の「COST」と「BYTE」...
-
文字数5000字、文字コードが2バ...
-
GB と Gbの違いの意味
-
アルファベット30文字は何バイ...
-
新聞1ページは何バイトですか?...
-
32bit = 4GB(バイト)?
-
カナカナの(半)濁点がついた文...
-
DVD-R 4.7GBって、何byte でし...
-
マトリックスサイズが512×512で...
-
Oracle AL32UTF8でのバイトサイ...
-
1Mbpsって毎秒何キロバイト?
おすすめ情報