Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> итерация от старшего байта к младшему, в безразмерных интах 
V
    Опции темы
leniviy
Дата 1.3.2011, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Пример:
Код

typedef char int56[7];

Как получить указатель на старший байт, и дойти до младшего? Порядок байтов зависит от платформы.

Код

#include <stdio.h>

typedef union {
    int i;

    unsigned char uchars[4];

} testunion;


int main() {
  testunion un;
  un.i = 0x01234567;
  printf("%d (0x%08x)\n", (int)un.i, (int)un.i);
  printf("%02hx %02hx %02hx %02hx\n", (short)un.uchars[0], (short)un.uchars[1], (short)un.uchars[2], (short)un.uchars[3]);
  fflush(stdout);
  return 0;
}

x86
Код

19088743 (0x01234567)
67 45 23 01

sparc:
Код

19088743 (0x01234567)
01 23 45 67



Это сообщение отредактировал(а) leniviy - 1.3.2011, 13:52
PM MAIL   Вверх
xvr
Дата 1.3.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Функции htonl и ntohl - преводят данные в фиксированный byte order


PM MAIL   Вверх
leniviy
Дата 1.3.2011, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Круто, но они не помогут с большими числами

Вот, написал такую конструкцию. На одних системах _endian.c будет 1, на других -1
Код

static const union {
  int i;
  char c;
} _endian = { (0xFF << ((sizeof(int)-1)*8)) | 0x01 };

Жаль, хотел на чистых макросах, без переменных.


Это сообщение отредактировал(а) leniviy - 1.3.2011, 14:46
PM MAIL   Вверх
xvr
Дата 1.3.2011, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(leniviy @ 1.3.2011,  14:36)
Круто, но они не помогут с большими числами

'Большие' - это сколько? Если 64 бита, то не помогут, увы  smile Если больше, то это уже массив слов в памяти, а он обычно на всех платформах располагается от младших адресов к старшим.

Можно проверить порядок байтов в run-time и перевернуть. Но это накладные расходы  smile 

PM MAIL   Вверх
mes
Дата 1.3.2011, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(xvr @  1.3.2011,  13:45 Найти цитируемый пост)
Можно проверить порядок байтов в run-time

а зачем проверять рантайм? когда и так известно будет на какую целевую платформу компилируют ?



--------------------
PM MAIL WWW   Вверх
leniviy
Дата 1.3.2011, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(mes @  1.3.2011,  14:47 Найти цитируемый пост)

а зачем проверять рантайм? когда и так известно будет на какую целевую платформу компилируют ?

Где известно? Есть стандартный макрос, у которого может быть 2 значения, типа 0 BE/1 LE? 
PM MAIL   Вверх
mes
Дата 1.3.2011, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



у gcc вроде есть такой макрос.. что то типа __LITTLE_ENDIAN__

а что мешает вручную задавать этот макрос в зависимости от платформы под которую компилите ?



--------------------
PM MAIL WWW   Вверх
leniviy
Дата 1.3.2011, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Тогда уж надо полноценный ./configure скрипт использовать. Остановился на своём способе, вопрос решен.
Код

static const union {
  int i;
  char c;
} _endian = { (0xFF << ((sizeof(int)-1)*8)) | 0x01 };

#define BYTEOFFS(nbyte, size) (_endian.c == 1 ? (nbyte) : ( (size) - 1 - (nbyte)))
#define BYTEPTR(ptr, nbyte, size) (((char*)(ptr)) + BYTEOFFS(nbyte, size))

#define BYTERANGEOFFS(startbyte, endbyte, size) (_endian.c == 1 ? (startbyte) : ( (size) - 1 - (endbyte)))
#define BYTERANGEPTR(ptr, startbyte, endbyte, size) (((char*)(ptr)) + BYTERANGEOFFS(startbyte, endbyte, size))

#define NEXTBYTEPTR(ptr) (((char*)(ptr)) + _endian.c)
#define PREVBYTEPTR(ptr) (((char*)(ptr)) - _endian.c)



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0894 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.