Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Получить int из char / 25 сообщений из 25, страница 1 из 1
14.01.2015, 12:16
    #38853963
DrumAsm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Здравствуйте. Пишу программу в Visual Studio 2008. Проект Win32.
Подскажите, имеется

Код: plaintext
1.
unsigned char p[] = {0x20, 0x00, 0xA3, 0x45, 0x89, 0x41 };



Как получить
Код: plaintext
1.
short int i

из значений
Код: plaintext
1.
p[1]

и
Код: plaintext
1.
p[2]

. В данном случае i должно быть равно 163. Я сделал так:

Код: plaintext
1.
i=p[2]*256+p[1];



Мне кажется, что это примитивно. Может есть другие варианты? Потому что long long int таким методом не удобно получать. Цикл наверное тоже не красиво будет смотреться. Спасибо.
...
Рейтинг: 0 / 0
14.01.2015, 12:37
    #38853992
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsmМне кажется, что это примитивно
Ну замени умножение на сдвиг для "продвинутости".

Это решение, в отличии от каста, не зависит от процессора.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
14.01.2015, 13:06
    #38854057
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsmВ данном случае i должно быть равно 163. Я сделал так: i=p[2]*256+p[1];
Так у тебя будет 0xA300
163 будет так p[1]*256+p[2]

Если все-таки правильно считать так как ты написал, то можно так
Код: plaintext
1.
unsigned short i = *((unsigned short*)&p[1]);


Если правильно как я написал, то *256 но делать это в цикле
Код: plaintext
1.
2.
3.
4.
5.
int res = 0;
for(int i = 1; i <= 2; i++) {
   res *= 256;
   res += p[i];
}
...
Рейтинг: 0 / 0
14.01.2015, 13:23
    #38854092
DrumAsm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Dima T,

Точно! 0xA300. Sorry. Это я уже запарился.. А в первом случае просто переносится указатель?
...
Рейтинг: 0 / 0
14.01.2015, 13:33
    #38854115
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsmDima T,

Точно! 0xA300. Sorry. Это я уже запарился.. А в первом случае просто переносится указатель?
Нет, читается значение, но читается как тип unsigned short. А т.к. unsigned short это два байта, то кроме p[1] берется p[2].
ХЗ как еще объяснить.
если пошагово расписать то вот что происходит:
Код: plaintext
1.
2.
3.
unsigned char* pp = &p[1];
unsigned short* pi = (unsigned short*) pp;
unsigned short i = *pi;
...
Рейтинг: 0 / 0
14.01.2015, 13:41
    #38854136
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Это решение чувствительно к архитектуре процессора — на одних архитектурах результат будет 0xA300, на других 0x00A3, на третьих результат не определён, на четвёртых программа упадёт. Лучше уж сдвигами.
...
Рейтинг: 0 / 0
14.01.2015, 13:42
    #38854140
DrumAsm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Dima T,

А вот всегда интересовал такой вопрос. Можно указателю unsigned short i присвоить адрес p[1], чтобы из указателя i я мог получить p[1] и p[2]?
...
Рейтинг: 0 / 0
14.01.2015, 13:59
    #38854180
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsm, в том то и весь цимес брат. Можно. Это похоже на езду без ремней безопасности.
Быстро и опасно. Но можно. На сях. В отличие от этих ваших шарпов и джав.
...
Рейтинг: 0 / 0
14.01.2015, 14:04
    #38854186
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsmDima T,

А вот всегда интересовал такой вопрос. Можно указателю unsigned short i присвоить адрес p[1], чтобы из указателя i я мог получить p[1] и p[2]?
брр ... ты сам понял что написал? Сделать из указателя char указатель short чтобы потом из него извлекать char. Можно, но зачем?
...
Рейтинг: 0 / 0
14.01.2015, 14:27
    #38854221
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
RWolfЭто решение чувствительно к архитектуре процессора — на одних архитектурах результат будет 0xA300, на других 0x00A3, на третьих результат не определён, на четвёртых программа упадёт. Лучше уж сдвигами.
Вроде уже не осталось архитектур где будет 0x00A3 (т.н. big endian), а "результат не определён" вообще из области фантастики.

Недавно пробовал откомпилировать одну свою программулину с подобными конструкциями под ARM-процессор - запустилось, работало корректно, общалась по сетке с другой прогой под виндой. Возможно есть какая-то экзотическая электроника с big endian, но если ТС до нее доберется, то, думаю, проблема big endian будет не самой серьезной.
...
Рейтинг: 0 / 0
14.01.2015, 14:29
    #38854222
DrumAsm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Dima T,

извлекать не char, а short int. Он же из себя и будет представлять p[2]*256+p[1] ? Или я ошибаюсь?
...
Рейтинг: 0 / 0
14.01.2015, 14:42
    #38854245
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Dima T,

не определён — это ARM ниже v7. В зависимости от ядра невыровненный доступ к данным может как менять порядок чтения байт, так и прерывать выполнение. Выровненный доступ при этом будет работать нормально.
...
Рейтинг: 0 / 0
14.01.2015, 14:43
    #38854247
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsmDima T,

извлекать не char, а short int. Он же из себя и будет представлять p[2]*256+p[1] ? Или я ошибаюсь?
Все верно.

Я же тебе выше подробно расписал что происходит. Если надо указатель на short то сокращенно так:
Код: plaintext
1.
unsigned short* pi = (unsigned short*)&p[1];



суть такая: ты даешь указание компилятору рассматривать последовательность байт не как массив, а как значение другого типа (размером больше байта), т.е. например в памяти лежит массив байт
Адрес значение123400x20123410x00123420xA3123430x45123440x89
Если этот кусок памяти рассматривать как массив char то для получения значения p[1] будет взято значение байта по адресу 12341, т.е. 0x00
Если посчитать что по адресу 12341 лежит значение типа short, то будут взяты два байта 0x00 и 0xA3 и т.к. принят порядок хранения от младшего к старшему, то процессор посчитает это числом 0xA300
Если захочешь прочитать как тип int (4 байта) то получится 0x8945A300. Подробнее тут
...
Рейтинг: 0 / 0
14.01.2015, 15:19
    #38854325
DrumAsm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Dima T,

спасибо, получилось)) А если вот так? short * i = reinterpret_cast<short*>(&p[1]); Читал, что не желательно это использовать, но всё же..
...
Рейтинг: 0 / 0
14.01.2015, 15:24
    #38854338
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsmА если вот так? short * i = reinterpret_cast<short*>(&p[1]);
не знаю что такое reinterpret_cast, это из С++, я с ним слабо дружу.
...
Рейтинг: 0 / 0
14.01.2015, 15:33
    #38854351
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Кроме порядка байтов следует еще учитывать что не на всех платформах можно читать слова большие байта по невыравненным адресам.

Если же не учитывать выравнивание, то считывать big endian можно так:
Код: plaintext
1.
2.
short i = ntohs(*(short*)&p[1]);
long i = ntohl(*(long*)&p[1]);
...
Рейтинг: 0 / 0
14.01.2015, 16:30
    #38854440
DrumAsm
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Всем спасибо за помощь. Всё получилось. Кому тоже интересно, вот варианты:
Код: plaintext
1.
short * i = reinterpret_cast<short*>(&p[1]);


или
Код: plaintext
1.
unsigned short* i = (unsigned short*)&p[1];
...
Рейтинг: 0 / 0
14.01.2015, 18:09
    #38854545
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsm, а тебе интересно узнать в чем разница между этими вариантами?
...
Рейтинг: 0 / 0
15.01.2015, 13:19
    #38855159
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
DrumAsm
Как получить
Код: plaintext
1.
short int i

из значений
Код: plaintext
1.
p[1]

и
Код: plaintext
1.
p[2]

. В данном случае i должно быть равно 163. Я сделал так:

Код: plaintext
1.
i=p[2]*256+p[1];



Мне кажется, что это примитивно.



На самом деле это -- лучший вариант. Тут нет неопределённого поведения и всё явным образом определено.
Можно заменить ещё умножения на сдвиги и сложения на побитовое ИЛИ -- это просто более простые операции.
Но в принципе это одно и то же.
...
Рейтинг: 0 / 0
15.01.2015, 15:45
    #38855360
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Арифметически-чистый.
...
Рейтинг: 0 / 0
16.01.2015, 02:27
    #38855694
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Здравствуйте.

Anatoly MoskovskyКроме порядка байтов следует еще учитывать что не на всех платформах можно читать слова большие байта по невыравненным адресам.

Если же не учитывать выравнивание, то считывать big endian можно так:
Код: plaintext
1.
2.
short i = ntohs(*(short*)&p[1]);
long i = ntohl(*(long*)&p[1]);



Если мы работаем только с artithmetic types, то в каком случаем данная конструкция будет работать некорректно ?
Код: plaintext
1.
T2=*(T2*)&object;



Если &object адрес элемента массива A и &object+sizeof(T) адрес элемента массива A. Объекты массива А имеют тип T1
...
Рейтинг: 0 / 0
16.01.2015, 02:39
    #38855695
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
почему вообще сложилось так, что little-endian и big-endian имеют место быть вместе ? Неужели когда проектировался фундамент, не было конференций и встреч разработчиков ведущих IT компаний, и они не могли согласовать стандарт, которого все должны были придерживаться ?
прошу прощение за офтоп.
...
Рейтинг: 0 / 0
16.01.2015, 05:53
    #38855713
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
SashaMercuryЕсли мы работаем только с artithmetic types, то в каком случаем данная конструкция будет работать некорректно ?
Код: plaintext
1.
T2=*(T2*)&object;


Я же написал:
Anatoly MoskovskyЕсли же не учитывать выравнивание

SashaMercuryпочему вообще сложилось так, что little-endian и big-endian имеют место быть вместе ? Неужели когда проектировался фундамент, не было конференций и встреч разработчиков ведущих IT компаний, и они не могли согласовать стандарт, которого все должны были придерживаться ?
прошу прощение за офтоп.
А также всех пересадить за одну ОС, поселить в одинаковых домах и заставить ездить только на метро )))
...
Рейтинг: 0 / 0
16.01.2015, 06:12
    #38855716
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
SashaMercuryпочему вообще сложилось так, что little-endian и big-endian имеют место быть вместе ?
Вообще конечно, все стандарты диктуются экономикой.
Изначально большинство применяло big-endian, потому что он ближе к человеческому представлению чисел, а компьютеры при реализации разных фич могли себе позволить занимать любой физический объем.
Но когда появились первые микропроцессоры с ограничением на размер оборудования и количество элементов в нем, то для экономии транзисторов стали применять такое размещение данных, которое соответствует алгоритмам обработки.
В частности арифметические операции производятся от младших разрядов к старшим.

Так и появилось два подхода, потому что существующий big-endian никто естественно не стал отменять - ничего личного, просто бизнес :)
...
Рейтинг: 0 / 0
16.01.2015, 06:14
    #38855717
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить int из char
Anatoly Moskovsky, понятно.
Спасибо :)
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Получить int из char / 25 сообщений из 25, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]