В зависимости от процессора данные в памяти могут хранится по-разному. Возьмём для примера целое число размером 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 байт. А также в том, что определяет смешанный порядок.
Комментариев нет:
Отправить комментарий