Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/40: Рейтинг темы: голосов - 40, средняя оценка - 4.90
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

Порядок байт

24.02.2020, 18:17. Показов 11022. Ответов 88
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте,

Подскажите пожалуйста, вот есть:
C++
1
int m_int = 1073741824;  //в двоичном представлении: 01000000 00000000 00000000 00000000
Если к этому числу применить маску:
C++
1
2147483648 //  в двоичном представлении: 10000000 00000000 00000000 00000000
Если применить логическое сложение:
C++
1
2
3
4
5
6
7
cout << (m_int & 2147483648) << endl;
 
01000000 00000000 00000000 00000000
10000000 00000000 00000000 00000000
 
То естественно получим 0:
10000000 00000000 00000000 00000000
Если сделать сдвиг бита вЛево:
C++
1
2
3
4
5
6
7
8
cout << ((m_int<<1) & 2147483648) << endl;
 
    0<<1000000 00000000 00000000 000000000
           10000000 00000000 00000000 00000000
 
То получим: 2147483648
 
           10000000 00000000 00000000 00000000
То есть байта int`а слева направо.

Но, если сделать так:
C++
1
char * m_ptr_char = (char*)m_int;
И вывести 4 элемента int в качестве значения char:

C++
1
2
3
4
cout<<(int)m_ptr_char[0]<<endl;
cout<<(int)m_ptr_char[1]<<endl;
cout<<(int)m_ptr_char[2]<<endl;
cout<<(int)m_ptr_char[3]<<endl;
Выведется:
C++
1
2
3
4
0
0
0
64
То есть первый элемент будет 0 и только 4ый будет 64: b01000000

То есть компьютер просматривает байты в int справо налево, противоположно привычно-человеческому слева направо ? :
C++
1
00000000 00000000 00000000 01000000
Это связано вот с этими странными понятиями bigendian, littleendian ?

Если да, то подскажите пожалуйста:

1)Но если сделать сдвиг бита << влево, то бит сдвигается влево. То есть bigendian, littleendian - влияет только на байты, а не биты внутри байта ?

2) bigendian, littleendian - зависит от ОС или от процессора ? И есть функция, как определить какая из этих штук действует условно на моем компе ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.02.2020, 18:17
Ответы с готовыми решениями:

Порядок следования байт
Привет. Есть флаги: None = 0x000, DateTimeFormat = 0x001, ... Diagnoses = 0x010, ......

Порядок байт в union
#include &lt;iostream&gt; using namespace std; void disp_binary(unsigned u); union swap_bytes { short int num; char ch; ...

Порядок байт у числовой переменной
Здравствуйте. Можно ли как то указать у числовой переменной чтоб байты у нее должны быть little endian

88
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
26.02.2020, 22:30
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от liv Посмотреть сообщение
Ага, а если значение икса будет, например, 0x0201. Что тогда даст чтение *((char*)&x)?
UB.
Пока значение x влазит в диапазон представимых значений для char, чтение через x lvalue и через *((char*)&x) lvalue даёт одно и то же значение.
Если значение не влазит в диапазон то при чтении *((char*)&x) будет UB.

Так стандарт написан.
0
 Аватар для COKPOWEHEU
4139 / 2717 / 433
Регистрация: 09.09.2017
Сообщений: 12,050
27.02.2020, 10:55
Цитата Сообщение от Azazel-San Посмотреть сообщение
Стандарт предполагает, что такое может быть.
Где?! Вот как хотите, а я не верю, что стандарт языка предусматривает возможность обратиться к несуществующей памяти вроде отрицательной ячейки.
Цитата Сообщение от liv Посмотреть сообщение
И что делать с union, в которых совмещаются int и 4 байта? Тоже вне закона?
Да, ведь поведение на разных системах будет различаться. Не считая того, что int далеко не всегда 4 байта.
Цитата Сообщение от argcargv Посмотреть сообщение
Про чтение значения через *(char*)&x, когда значение не в диапазоне char, явно сказано что UB.
Так ведь именно поэтому вариант liv и может работать. Если бы не UB, всегда возвращалось бы одно и то же число, 0 или 1 независимо от архитектуры, ОС и прочего.
Цитата Сообщение от liv Посмотреть сообщение
Если каст инта на чар есть UB, то почему юнион разрешен?
Хотя с юнион в целом понятно. Вопрос снимаю
Эй! А как же остальным рассказать?
Скажем, что union позволяет хранить в одной и той же памяти разные типы данных, но не требует их одновременного использования. Например, в SDL (SDL_events.h) такое используется для вообще любых событий: выставляется флажок события, а остальные байты приводятся к той или иной структуре.
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
typedef struct SDL_UserEvent
{
    Uint32 type;        /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */
    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
    Uint32 windowID;    /**< The associated window if any */
    Sint32 code;        /**< User defined event code */
    void *data1;        /**< User defined data pointer */
    void *data2;        /**< User defined data pointer */
} SDL_UserEvent;
typedef struct SDL_SysWMEvent
{
    Uint32 type;        /**< ::SDL_SYSWMEVENT */
    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
    SDL_SysWMmsg *msg;  /**< driver dependent data, defined in SDL_syswm.h */
} SDL_SysWMEvent;
typedef union SDL_Event
{
    Uint32 type;                    /**< Event type, shared with all events */
    SDL_CommonEvent common;         /**< Common event data */
    SDL_DisplayEvent display;       /**< Window event data */
    SDL_WindowEvent window;         /**< Window event data */
    SDL_KeyboardEvent key;          /**< Keyboard event data */
    SDL_TextEditingEvent edit;      /**< Text editing event data */
    SDL_TextInputEvent text;        /**< Text input event data */
    SDL_MouseMotionEvent motion;    /**< Mouse motion event data */
    SDL_MouseButtonEvent button;    /**< Mouse button event data */
    SDL_MouseWheelEvent wheel;      /**< Mouse wheel event data */
    SDL_JoyAxisEvent jaxis;         /**< Joystick axis event data */
    SDL_JoyBallEvent jball;         /**< Joystick ball event data */
    SDL_JoyHatEvent jhat;           /**< Joystick hat event data */
    SDL_JoyButtonEvent jbutton;     /**< Joystick button event data */
    SDL_JoyDeviceEvent jdevice;     /**< Joystick device change event data */
    SDL_ControllerAxisEvent caxis;      /**< Game Controller axis event data */
    SDL_ControllerButtonEvent cbutton;  /**< Game Controller button event data */
    SDL_ControllerDeviceEvent cdevice;  /**< Game Controller device event data */
    SDL_AudioDeviceEvent adevice;   /**< Audio device event data */
    SDL_SensorEvent sensor;         /**< Sensor event data */
    SDL_QuitEvent quit;             /**< Quit request event data */
    SDL_UserEvent user;             /**< Custom event data */
    SDL_SysWMEvent syswm;           /**< System dependent window event data */
    SDL_TouchFingerEvent tfinger;   /**< Touch finger event data */
    SDL_MultiGestureEvent mgesture; /**< Gesture event data */
    SDL_DollarGestureEvent dgesture; /**< Gesture event data */
    SDL_DropEvent drop;             /**< Drag and drop event data */
    Uint8 padding[56];
} SDL_Event;

Цитата Сообщение от liv Посмотреть сообщение
Azazel-San, да знаю я, что такое UB (undefined behavior, неопределенное поведение), знаю.
Чуть выше об этом писал: у вас алгоритм на этом построен.
UB тут только в том, что неизвестно какой байт попадет в начало переменной. Они могут идти как 1234, могут как 4321, могут как 3412, да хоть 00001234.
Цитата Сообщение от argcargv Посмотреть сообщение
Пока значение x влазит в диапазон представимых значений для char, чтение через x lvalue и через *((char*)&x) lvalue даёт одно и то же значение.
Если значение не влазит в диапазон то при чтении *((char*)&x) будет UB.
Ничего подобного. Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 12:41
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если бы не UB, всегда возвращалось бы одно и то же число, 0 или 1 независимо от архитектуры, ОС и прочего.
Кстати, да
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Да, ведь поведение на разных системах будет различаться. Не считая того, что int далеко не всегда 4 байта.
А поведение и сейчас отличается. У каждой системы свой набор инструментов. И всегда будет отличаться друг от друга. Чего-то меня гложат сомнения, что будут писаться программы, которые будут сходу работать как на x86, так и на той же Motorola.
А вот совать палки в колеса разработкам на одной и той же постоянной системе с кастами, как-то нехорошо.
Размер в 4 байта был взят условно. В некоторых union, всегда 4 байта, например IN_ADDR
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Эй! А как же остальным рассказать?
Так понимаю, применение union для доступа к составляющим частям более крупного объекта не должно приводить к проблемам, т.к. будет явное обращение к нужному месту. И не важно в каком они порядке! А вот после каста (см чуть далее)...
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
UB тут только в том, что неизвестно какой байт попадет в начало переменной. Они могут идти как 1234, могут как 4321, могут как 3412, да хоть 00001234
Да-да, на этом и построет алгоритм.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес
Уважаемые оппоненты утверждают, что все равно будет читаться единица. Т.к. объект остается int-ом! UB нет, т.к. int помещается в char. Прочитанный int усекается до байта и получаем на выходе байт 0x01. Вот такие пироги!

Добавлено через 4 минуты
Еще раз процитирую:
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если бы не UB, всегда возвращалось бы одно и то же число, 0 или 1 независимо от архитектуры, ОС и прочего
Именно об этом оппоненты и говорят

Добавлено через 3 минуты
Отсюда вывод, граждане: в данном контексте UB необходим, т.к. позволяет определить систему!
0
 Аватар для COKPOWEHEU
4139 / 2717 / 433
Регистрация: 09.09.2017
Сообщений: 12,050
27.02.2020, 13:06
Цитата Сообщение от liv Посмотреть сообщение
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес.
Уважаемые оппоненты утверждают, что все равно будет читаться единица. Т.к. объект остается int-ом! UB нет, т.к. int помещается в char. Прочитанный int усекается до байта и получаем на выходе байт 0x01. Вот такие пироги!
При преобразовании int->char идет работа со значениями, тут результат однозначный (забудем пока про знаковость и прочие не относящиеся к нашей теме вещи)
При преобразовании int*->char* идет работа с указателями, а сами значения остаются неизменными. И значение по указателю уже будет зависеть от способа хранения.
Цитата Сообщение от liv Посмотреть сообщение
Уважаемые оппоненты утверждают, что все равно будет читаться единица.
Но ведь не читается. Точнее, не всегда читается. Это что, они таким способом нашли баг в компиляторе, что он делает что-то, противоречащее стандарту?
Цитата Сообщение от liv Посмотреть сообщение
Так понимаю, применение union для доступа к составляющим частям более крупного объекта не должно приводить к проблемам, т.к. будет явное обращение к нужному месту. И не важно в каком они порядке! А вот после каста (см чуть далее)...
Это не понял.
Мой-то пример был проще: если у нас есть объединение int и char[4], то если мы пишем в int, а читаем из char[], получаем UB. А если пишем в int, читаем из int, либо пишем в char[], читаем из char[] - вполне себе определенное поведение.
Именно это и используется в SDL: одна и та же переменная может трактоваться как один из нескольких типов данных на выбор. При этом если перепутать тип при чтении - закономерно получишь мусор.
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 18:02
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ничего подобного. Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес.
Пруфов, конечно, не будет.
Цитата Сообщение от liv Посмотреть сообщение
Уважаемые оппоненты утверждают, что все равно будет читаться единица.
Стандарт. Стандарт утверждает.
0
0 / 1 / 0
Регистрация: 10.07.2017
Сообщений: 8
27.02.2020, 18:17
Цитата Сообщение от argcargv Посмотреть сообщение
UB.
Пока значение x влазит в диапазон представимых значений для char, чтение через x lvalue и через *((char*)&x) lvalue даёт одно и то же значение.
Если значение не влазит в диапазон то при чтении *((char*)&x) будет UB.
Так стандарт написан.
А можна конкретную ссылочку на вординг?
Спасибо.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 18:27
Kovacz, мне уже здесь отвечали на этот вопрос. Вот, посмотрите теперь Вы
0
0 / 1 / 0
Регистрация: 10.07.2017
Сообщений: 8
27.02.2020, 18:41
liv, меня интересовала ссылочка где описывается именно об не попадании в диапазон char. Как я понимаю, эта ситуация исходя из слов argcargv явно описана в стандарте и приводит к UB, я вот пока этого не нашел, хотел бы конкретную ссылочку.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 18:45
Я также внимательно слежу за этим вопросом...
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 20:15
Kovacz, liv, вы меня поражаете. Что в следующем коде UB это новость?
C++
1
2
int i = INT_MAX;
i + 1;
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
27.02.2020, 20:51
Цитата Сообщение от argcargv Посмотреть сообщение
Пруфов, конечно, не будет.
Вот. Даже с названиями платформ.
1
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 21:33
argcargv, это не новость, причем результат известен всегда
Но это из другой оперы

Добавлено через 2 минуты
avgoor, именно UB используется для определения платформы.
Т.к. в каждой платформе своя организация
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
27.02.2020, 21:36
Цитата Сообщение от liv Посмотреть сообщение
именно UB используется для определения платформы.
Не путайте UB с "определяется реализацией"
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 21:42
avgoor, вот это "определяется реализацией" давайте адресуем нашим оппонентам
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 23:00
Цитата Сообщение от avgoor Посмотреть сообщение
Вот.
> ru
> wikipedia
> пруф
Это даже не смешно. Можно ещё "пруф" с луркомора или абсурдопедии?
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
27.02.2020, 23:02
Цитата Сообщение от argcargv Посмотреть сообщение
Это даже не смешно.
Т.е. тот факт, что на SPARC-е будет 0 вас не смутил?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 23:30
Цитата Сообщение от avgoor Посмотреть сообщение
Т.е. тот факт, что на SPARC-е будет 0 вас не смутил?
А тот факт что мы тут обсуждаем что стандарт требует вас не смутил?
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
28.02.2020, 00:19
Цитата Сообщение от argcargv Посмотреть сообщение
А тот факт что мы тут обсуждаем что стандарт требует вас не смутил?
Меня - нет. Просто его читать надо уметь.

Ну, ладно. А в этом коде UB есть?
C++
1
2
3
4
    char* c = (char*)malloc(4);
    int32_t* i = new(c) int32_t(1);
    std::cout << (c[0] == 0 ? "big" : "little");
    free(c);
0
 Аватар для COKPOWEHEU
4139 / 2717 / 433
Регистрация: 09.09.2017
Сообщений: 12,050
28.02.2020, 11:26
Цитата Сообщение от argcargv Посмотреть сообщение
Пруфов, конечно, не будет.
А какие еще нужны пруфы кроме использования этого факта людьми?
Цитата Сообщение от argcargv Посмотреть сообщение
Стандарт. Стандарт утверждает.
Может, стоило его почитать, прежде чем нести чушь?
Цитата из стандарта:
When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object
"При преобразовании указателя к char*, результат указывает на младший (по адресу) байт объекта". Следовательно, если архитектура little-endian (младший байт имеет меньший адрес), адресован будет младший, если big-endian (старший байт раньше) - то старший.
Как вообще по-другому можно понять различие big-endian и little-endian?
0
0 / 1 / 0
Регистрация: 10.07.2017
Сообщений: 8
28.02.2020, 11:43
Цитата Сообщение от argcargv Посмотреть сообщение
Что в следующем коде UB это новость?
То все дело в обычном переполнении? Соответственно если там будет unsigned char - UB не будет?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.02.2020, 11:43

Порядок байт в слове и бит в байте
читал эту требуются пояснения. A B C D - адреса в них число 128 BE A B C D ...

Определить порядок хранения байт 16-ричного числа
Всем привет! Имеется следующий вопрос: написать программу, которая показывает порядок хранения байт 16-ричного числа. Как это сделать?

Порядок байт. Массив чаров приводится к типу unsigned int.
Есть массив из 4 char. Массив приводится к типу unsigned int и затем данные извлекаются в переменную типа unsigned int. Нужно, чтобы байты...

Порядок байт в big-endian и little-endian
Всем привет! Народ подскажите мне пожалуйста простые прописные истины, а то я что то запутался! Предположим что у нас в байте 8 - бит и...

Закодировать файл. Взять 7 байт. Первый бит каждого байта переместить в 8 байт
Нужно открыть бинарный файл и закодировать следующим образом. Взять 7 байт. Первый бит каждого байта переместить в 8 байт. То есть,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ начало и оглавление - Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование. . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru