a wandering wolf

Does a wandering wolf dreams of a wondering, sometimes programming sheep?

このエントリーをはてなブックマークに追加

整数をビッグエンディアンのバイト配列に変換する

お仕事でC言語を触ることになりまして、日々あくせくしております。他の言語なら便利なライブラリがあるところ、C言語だと「さぁ、頑張ってみよう」みたいな感じで、自力でやらなくちゃいけないので、私のような温室育ちマンには大変ですね。

ちょうど本タイトルのようなことをやる場面に遭遇したので、備忘録がてら書き残します。

目的

ある整数を同じバイト数のバイト配列に変換する、ということを考えています。変換方法としては、次のような共用体を使うアイディアがあります。

union int32_u
{
    int32_t value;        /* 整数値 */
    uint8_t binary[4];    /* バイト配列 */
};

ここで、実行環境のアーキテクチャがリトルエンディアンである場合、そのままバイト表現に落とし込むと並び順もリトルエンディアンのものになります。

#include <stdint.h>

union int32_u
{
    int32_t value;
    uint8_t binary[4];
};

int main(void)
{
    union int32_u uni;
    uni.value = 33 - 4;
    /*
     * uni.binary: [ 0x1D, 0x00, 0x00, 0x00 ]
     */
    return 0;
}

通信を行う場合、送信するメッセージに含まれるデータをビッグエンディアンとして設定する、ということはままあります。このような条件がある場合、整数→ビッグエンディアンとしてのバイト配列、という変換をしたくなります。

対応方法

void int32_to_big(int32_t value, uint8_t *binary)
{
    union int32_u uni;
    uni.value = value;
    *binary = *(uni.binary + 3);
    *(binary + 1) = *(uni.binary + 2);
    *(binary + 2) = *(uni.binary + 1);
    *(binary + 3) = *uni.binary;
}

このような関数を用意しておきます。

int main(void)
{
    uint8_t binary[4] = {0};
    int32_to_big(33 - 4, binary);
    /*
     * binary: [ 0x00, 0x00, 0x00, 0x1D ]
     */
    return 0;
}

良い感じですね。

なお、ここまで特に配列の要素数チェックは行っていないので、必要であれば追加してください。