Почему существуют и utf-16le, и utf-16be? эффективность порядка следования байтов - C

Мне было интересно, почему существуют и utf-16le, и utf-16be? Считается ли «неэффективным» для среды с прямым порядком байтов обрабатывать данные с прямым порядком байтов?

В настоящее время это то, что я использую при локальном хранении 2 байтов var:

  unsigned char octets[2];
  short int shotint = 12345; /* (assuming short int = 2 bytes) */
  octets[0] = (shortint) & 255;
  octets[1] = (shortint >> 8) & 255);

Я знаю, что при локальном хранении и чтении с фиксированным порядком байтов нет риска байтов. Мне было интересно, считается ли это «неэффективным»? что было бы наиболее «эффективным» способом хранения 2-байтовой переменной? (при ограничении данных порядком байтов среды, только локальное использование.)

Спасибо, Дори Бар.


person Doori Bar    schedule 27.07.2010    source источник


Ответы (1)


Это позволяет коду записывать большие объемы данных Unicode в файл без преобразования. Во время загрузки вы всегда должны проверять порядок байтов. Если вам повезет, вам не нужно преобразование. Таким образом, в 66% случаев вам не нужно конвертировать, и только в 33% вы должны конвертировать.

Затем в памяти вы можете получить доступ к данным, используя собственные типы данных вашего ЦП, что обеспечивает эффективную обработку.

Таким образом, каждый может быть максимально счастлив.

Итак, в вашем случае вам нужно проверить кодировку при загрузке данных, но в ОЗУ вы можете использовать массив short int для его обработки.

[EDIT] Самый быстрый способ преобразовать 16-битное значение в 2 октета:

char octet[2];
short * prt = (short*)&octet[0];
*ptr = 12345;

Теперь вы не знаете, является ли octet[0] младшими или старшими 8 битами. Чтобы выяснить это, напишите известное значение, а затем проверьте его.

Это даст вам одну из кодировок; родной из вашего процессора.

Если вам нужна другая кодировка, вы можете поменять местами октеты при записи их в файл (т.е. записать их octet[1],octet[0]) или свой код.

Если у вас есть несколько октетов, вы можете использовать 32-битные целые числа для одновременной замены двух 16-битных значений:

char octet[4];
short * prt = (short*)&octet[0];
*ptr ++ = 12345;
*ptr ++ = 23456;

int * ptr32 = (int*)&octet[0];
int val = ((*ptr32 << 8) & 0xff00ff00) || (*ptr >> 8) & 0x00ff00ff);
person Aaron Digulla    schedule 27.07.2010
comment
Спасибо за быстрый ответ, есть ли шанс, что вы можете показать мне базовый пример того, как преобразовать 2 байта var в 2 октета, изначально? (игнорируя порядок следования байтов, только для локального использования) - person Doori Bar; 27.07.2010
comment
Поправьте меня, если я ошибаюсь, но согласно вашему ответу я предположил, что мой код действительно неэффективен. (только для местного использования) - person Doori Bar; 27.07.2010
comment
Ваш код неэффективен, когда вы используете его для записи данных Unicode в файл (если только вы не должны использовать utf16-le в качестве кодировки). - person Aaron Digulla; 27.07.2010
comment
Это эффективный способ сделать это? codepad.org/4lESCv0G , или я все неправильно понял? - person Doori Bar; 27.07.2010
comment
Недоразумение :-) Ваш код эффективен, если вам нужно преобразовать 16-битный родной Unicode -> UTF-16LE. Я говорю, что вы должны попытаться избежать обращения. - person Aaron Digulla; 27.07.2010
comment
Но для кода на кодовой панели: Превратите octets в указатель char *, назначьте ему адрес shortint, а затем получите прямой доступ к значениям с помощью octet[0/1]. - person Aaron Digulla; 27.07.2010
comment
Не нужно ничего конвертировать ... Это 100% родная операция только для локального использования :) - моя вставка поверх codepad.org/4lESCv0G все еще конвертируется? - person Doori Bar; 27.07.2010
comment
Я вижу, спасибо большое! Я думаю, теперь ты мне все прояснил. - person Doori Bar; 27.07.2010
comment
Да, потому что вы копируете данные в памяти. Мое решение просто использует умную арифметику указателя. См. codepad.org/dBQ0WSaw. - person Aaron Digulla; 27.07.2010