2


0

ビッグエンディアンマシン(C)で4バイト整数から読み取った後に24ビットメッセージを書き込む方法

ネットワーク経由で24ビットの数値を送信するメッセージを作成しています。 リトルエンディアンマシンの場合、コードは次のとおりです(ptrはメッセージバッファーへのポインターです)。

*ptr++ = (num >> 16) & 0xFF;
*ptr++ = (num >> 8)  & 0xFF;
*ptr++ = (num)       & 0xFF;

(したがって、num0、num1、num2、num3がnumを構成する個々のバイトである場合、メッセージは `num2 | num1 | num0`としてエンコードされます。)

ビッグエンディアンのマシンで `num2 | num1 | num0`をエンコードするためのコードは何ですか?

4 Answer


3


ここでの質問は、_message_をどのバイト順で送信/構築するかです。 エンディアンに依存しない方法ですでに「num」を個々のバイトに分割しているため、リトルエンディアンまたはビッグエンディアンのどちらのマシン上にいるかは「num」に関して重要ではありません。

投稿したコードは、24ビットの `num`をビッグエンディアン(別名ネットワークバイトオーダー)で保存します。 それがあなたが望むものであるならば、あなたはすでに終わっています。 代わりに大きなサイズで保存したい場合は、順序を逆にするだけです:

*ptr++ = (num)       & 0xFF;
*ptr++ = (num >> 8)  & 0xFF;
*ptr++ = (num >> 16) & 0xFF;


1


エンディアンに関係なく、コードは移植可能です。 シフト演算子 `>>`と `<<`は、表現ではなく値で機能します。


0


受信側のマシンでは、エンディアンに関係なく、ptrに保存されているのと同じ順序で受信した場合、次のように組み立てます。

num = (ptr[0] << 16) + (ptr[1] << 8) + (ptr[2]);


0


int main(int argc, char** argv) {

    int a, b;
    a = 0x0f000000;        // Contain 32 bit value
    printf("before = %d\n", a);
    b = a & (~0xff000000); // convert the last 8 bits to zero so we got only 24 bit value in b
    printf("After = %d\n", b);
    return (EXIT_SUCCESS);
}

32ビット値を含む数値がありますが、数値bには最下位桁から始まる24ビットのみが含まれています。 また、ビット単位の演算子はメモリ表現では機能しないため、エンディアンに依存しません。

だからあなたは使用することができます

num = num & (~0xff000000);

最後の24ビット値を取得します。