В зависимости от процессора данные в памяти могут хранится по-разному. Возьмём для примера целое число размером 4 байта со значением 0x44332211 в 16-ной системе счисления. Для систем с остроконечным порядком (младшие байты располагаются по младшим адресам) это число будет хранится в виде последовательности байт 0x11 0x22 0x33 0x44. Для систем с тупоконечным порядком то же число будет хранится как 0x44 0x33 0x22 0x11. Есть ещё смешанные способы хранения. Об этом хорошо написано в http://ru.wikipedia.org/wiki/Порядок_байтов. На практике возникает задача - определить порядок хранения.
Для C++ данная задача решается следующим образом:
Особенность данного решения в том, что она рассматривает любые размеры long, включая 1, 2, 4, 8 байт. А также в том, что определяет смешанный порядок.
Для C++ данная задача решается следующим образом:
enum ENDIAN
{
ENDIAN_UNDEFINED = 0,
ENDIAN_LITTLE, // Порядок от младшего к старшему, остроконечный (младшие байты по младшим адресам)
ENDIAN_MIDDLE, // Смешанный порядок
ENDIAN_BIG // Порядок от старшего к младшему, тупоконечный, сетевой порядок (старшие байты по младшим адресам)
};
ENDIAN which_endian()
{
if (sizeof(long) == 1)
return ENDIAN_UNDEFINED;
union
{
long l;
unsigned char m[sizeof(long)];
} x;
// HERE: нельзя в x.l присвоить большее значение, например, x.l=0x8877665544332211; Это приведёт к ошибке компиляции на g++
x.l = 0;
for (size_t i=1; i<sizeof(long); i++)
x.l += i << (8*i);
bool is_ascending = true;
bool is_descending = true;
for (size_t i=1; i<sizeof(long); i++)
{
if (x.m[i-1] < x.m[i])
is_descending = false;
if (x.m[i-1] > x.m[i])
is_ascending = false;
}
if (is_ascending)
return ENDIAN_LITTLE;
if (is_descending)
return ENDIAN_BIG;
return ENDIAN_MIDDLE;
}
Особенность данного решения в том, что она рассматривает любые размеры long, включая 1, 2, 4, 8 байт. А также в том, что определяет смешанный порядок.
Комментариев нет:
Отправить комментарий