Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Как правильно прочитать 16-бит из char? |
Автор: RYB 23.5.2007, 21:26 | ||
Я сейчас работаю с hex-кодом ФАТ 12 и для того чтобы узнать где находится начало файла мне нада прочитать 2 байта, начиная с 26-го байта записи. Я пробовал работать с инт и чар, но в первом случае числа получаються астрономическими, а если с чаром, то просто 1-байтовыми(а мне нада 2 байта). ![]() Вобщем я понял как приобразовить чар в 2байта: если дано
Сам вопрос: как разбить значение одной переменной чар в две(с1=0х9, с2=0хВ)? ![]() |
Автор: zkv 23.5.2007, 21:33 | ||
RYB, вообщето char занимает 1 байт (или 8 бит) 0x9B(16) = 10011011(2) - наблюдаем 8 бит если вам надо разбить байт по 4 бита:
|
Автор: archimed7592 23.5.2007, 21:34 | ||
|
Автор: RYB 23.5.2007, 21:39 |
Спасибо, все дело в unsigned char: как я увидел на практике он занимает в отличии от чар 2 байта. |
Автор: codelord 23.5.2007, 21:41 | ||
c какой стати? |
Автор: bsa 23.5.2007, 21:48 | ||
sizeof(char) == sizeof(unsigned char) == 1 sizeof(short) == sizeof(unsigned short) == 2 sizeof(int) == sizeof(unsigned int) == 4 sizeof(long) == sizeof(unsigned long) == sizeof(void*) == 4 (для 32-х битных систем) или 8 (для 64-х битных) |
Автор: archimed7592 23.5.2007, 21:51 |
bsa, я так категорично утверждал бы только относительно char... кстати char - это unsigned char или signed char... |
Автор: bsa 23.5.2007, 21:59 |
обычно, char - это signed char. Но у компиляторов есть ключ, который char делает unsigned char. Но в любом случае: sizeof(unsigned char) == sizeof(signed char) == sizeof(char) Все сказанное мной справедливо для систем, разрядность которых 32 и 64 бита. |
Автор: RYB 23.5.2007, 22:01 |
Я сделал подобный вывод так как: если взять char c=0x9B, c=-101 unsigned char c=0x9B, c=155 + я юзаю прогу WinHex и в окошке Data Interpreter для 0x9B: 8bit=-101 16bit=155 |
Автор: bsa 23.5.2007, 22:14 | ||
И что? Все правильно. Примеры для signed char (8 бит) и signed short (16 бит):
|
Автор: zkv 23.5.2007, 23:01 |
друзья, получается я ошибаюсь здесь: и char в любом случае занимает 1 байт? Это стандарт так говорит? Откуда то ведь это осело в моей голове... |
Автор: Daevaorn 23.5.2007, 23:31 |
нет. стандарт не ограничивает. ты был прав. |
Автор: Fazil6 23.5.2007, 23:32 |
<sensored> Вообще байт на конкретной платформе должен обеспечивать хранение символа ASCII |
Автор: archimed7592 23.5.2007, 23:33 | ||||||
![]() угумс
![]() Добавлено через 41 секунду Daevaorn, ну блин, от тя не ожидал |
Автор: Fazil6 23.5.2007, 23:36 |
archimed7592, дело в том, что в стандарте 1 это строго говоря не 1 байт, а одна единица и в этих единицах меряются остальные типы |
Автор: Xenon 23.5.2007, 23:39 |
Fazil6, Я так понимаю, что все в char`ах исчисляется и один char - и есть та самая 1? Это я чтобы удостовериться ![]() |
Автор: archimed7592 23.5.2007, 23:39 | ||||
Fazil6, блин, двумя предложениямии раньше
Добавлено через 3 минуты и 15 секунд хотя...
|
Автор: Daevaorn 23.5.2007, 23:43 | ||||||||
![]()
|
Автор: archimed7592 23.5.2007, 23:44 |
ставлю "+" в репу тому, кто назовёт хоть одну реально существующую систему\платформу\компилятор, где byte не 8-ми битный ![]() Добавлено @ 23:51 Daevaorn, что у тебя за стандарт такой, где есть пункт 1.7.1? ![]() насчёт же реальных систем... вот, советую: http://www.viva64.com/articles/20%20issues%20of%20porting%20C++%20code%20on%20the%2064-bit%20platform.pdf http://rsdn.ru/article/mag/200701/XXtraps64bit.xml вот к примеру оттуда я узнал, что на windows-64 sizeof(long)!=sizeof(void *), bsa, как видишь, не для всех справедливо ![]() |
Автор: Daevaorn 23.5.2007, 23:55 | ||
Вроде самый последний на сегоднешний момент. |
Автор: archimed7592 23.5.2007, 23:59 |
ну ещё есть драфт... но в последнем драфте уж больно много новшевств, что порой начинаешь сверяться с Second Edition ![]() ммм... всегда думал, что циферки слева от текста - это так, для красоты ![]() |
Автор: Daevaorn 24.5.2007, 00:02 | ||
это номер стиха видимо ![]() |
Автор: Fazil6 24.5.2007, 00:02 | ||
да. Страуструп п.4.6 |
Автор: Xenon 24.5.2007, 00:03 |
Fazil6, Вот я оттуда и вспомнил ![]() |
Автор: archimed7592 24.5.2007, 00:15 |
ок, а есть какой-нибудь стандартный способ узнать сколько бит содержится в "байте"? ![]() |
Автор: Daevaorn 24.5.2007, 00:20 |
можно попробовать проанализировать результат нужного numeric_limits |
Автор: archimed7592 24.5.2007, 00:50 | ||
ммм... написал уже темплейт, считающий log2 в compile-time, когда до меня дошло, что в numeric_limits min и max - это ф-ции ![]() ![]()
тогда ещё вот проблемака: как узнать endianity (big-endian, low-endian)? compile-time, разумеется... |
Автор: Daevaorn 24.5.2007, 00:56 |
а такой есть? может little? ![]() |
Автор: nickless 24.5.2007, 18:44 | ||
endianess ![]() Можно написать проверку в мейкфайле и поставить соответствующий дефайн, примерно это делается например в automake & Co |
Автор: bsa 24.5.2007, 21:02 |
Господа, так что там насчет sizeof(char) == 1 решили? Уже не всегда? Или все-таки всегда? А то что-то вечером цитаты из стандарта плохо воспринимаются... |
Автор: archimed7592 24.5.2007, 21:19 |
bsa, решили, что всегда, но не всегда эта единица означает один байт... точнее она означает байт в интерпретации стандарта, где он может состоять не из 8-ми бит... напоминаю про своё обещание поставить + тому, кто назовёт хоть одну платформу\компилятор, где байт представляет из себя не 8 бит ![]() |
Автор: Hurricane 24.5.2007, 21:43 | ||
Архимед, тебя что, на Гугле забанили? ![]() http://en.wikipedia.org/wiki/Byte#Meanings Только, похоже, они все уже умерли. |
Автор: nickless 24.5.2007, 21:46 | ||
вот еще тут посмотри: ![]() http://en.wikipedia.org/wiki/36-bit_word_length
|
Автор: Daevaorn 24.5.2007, 21:51 |
archimed7592, кто-то кажется немного ошибся, а? ;) |
Автор: bsa 24.5.2007, 23:04 |
Что-то мне подсказывает, но программа уровня выше "hello world" на машинах, разрядность байта которых отлична от 8, будет работать несколько иначе, чем на остальных машинах. Начнем с того, что передача данных отличных от текста между 9-ти битной и 8-ми битной машинами будет представлять собой "определенную" сложность. На сколько я понял из последней ссылки начиная с IBM System/360 (анонсированой 7 апреля 1964 г) была введена практика на использование "слов", разрядность которых является степенью двойки. В то же время http://en.wikipedia.org/wiki/C_(programming_language). Так как нынче основной софт пишется на С/С++, то можно предположить, что мало кто отважится без крайней необходимости создать платформу, разрядность байта которой будет отлична от 8 бит, так как возникнет серьезная несовместимость. Причем не только программная. Или я неправ? Имхо, все эти выкрутасы с типами в стандарте Си ни к чему хорошему не приводят. Имхо, это был компромис. Чего только стоит sizeof(short) == sizeof(int) на 16-ти битных платформах (по крайней мере, в Borland C++ 3.1 под DOS) и sizeof(int) == sizeof(long) - на 32-х битных (windows и *nix). А что будет иметь тогда разрядность 128 или 16 бит на 128 битной платформе? Когда создаются структуры платформонезависимых файлов приходится вводить свои типы, типа UINT32, UINT16, UINT8... Думаю, не помешало бы ввести в Си на уровне стандарта дополнительные типы, например __int8, __int16, __int32, __int16b, __int32b, __int16l, __int32l (b - означает big endian, l - little endian)... Чтобы программист без введения конфигурируемых типов гарантированно имел доступ к нужному количеству разрядов в нужной последовательности. |
Автор: archimed7592 24.5.2007, 23:10 | ||||
ёп-та... скока плюсов то ставить... рука отсохнет ![]() Daevaorn, я не утверждал обратного... я просто захотел услышать от людей, сталкивались ли они в реальной жизни с такими системами... я имею ввиду не в музее/интернете видели, а именно программировали под них... ну да ладно, обещание своё выполню ![]() Hurricane++ nickless++ Добавлено через 13 минут и 35 секунд
all, а вот попробуйте на секундочку представить, каково станет программировать, если даже с малой долей вероятности нельзя будет предположить кол-во бит в байте, размер short/int/long/long long/new_int_type, порядок следования байт в слове(endianess)... ну и как перспективка? ;) |
Автор: nickless 24.5.2007, 23:53 | ||||||
Не знаю как будет на 128 битах, а с 64 уже сейчас весело, винда использует модель http://msdn.microsoft.com/library/default.asp?url=/library/en-us/win64/win64/abstract_data_models.asp, а *никс/мак - http://www.unix.org/version2/whatsnew/lp64_wp.html. Разница между ними - в LLP64 sizeof(int) = sizeof(long) = 4, sizeof(long long) = 8, а в LP64 sizeof(int) = 4, sizeof(long) = 8, и в обоих случаях sizeof(int) != sizeof(pointer)
Пожалуй было бы удобно, плохо только что очень уж много вариантов, особенно если учесть еще mixed endian и int64. ![]()
ИМХО если кто до сих пор использует такие платформы - пусть сам и мучается ![]() Ужасть... ![]() |
Автор: archimed7592 24.5.2007, 23:56 |
я извиняюсь, а как его учесть можно? ![]() ну вот на x86 с big-endian я сделаю __int32l x = 5... и чо это будет? ![]() |
Автор: nickless 25.5.2007, 00:05 |
Ну например добавить еще __int32m, __int64m итд ![]() На x86 little-endian ;) Я думаю такие типы можно было бы использовать для типов, которые предпологается записывать на диск/передавать куда-нибудь. Например в порограмме везде используем нативный int, а перед записью пишем его в __int32l и компайлер сам переставляет байты как надо, а мы сидим и наслаждаемся жизнью. ![]() |
Автор: archimed7592 25.5.2007, 00:10 | ||
ну не суть ;)
![]() |
Автор: bsa 25.5.2007, 10:07 | ||||||
А вот разработчики винды пошли по пути наименьшего сопротивления. Вот только не уверен, что именно он окажется более эффективным с точки зрения использования ресурсов процессора. Имхо, зачем тогда нужен тип long int, когда есть int того же размера?
Я именно про тоже. Нет никакого смысла в циклах и прочих внутренних вещах программы юзать всякие __int64l и __int64b. Это сильно скажется на быстродействии на "неродных" архитектурах. Но вот при формировании структур данных, записываемых в файл, такие типы очень бы пригодились.
![]() Кстати. Что-то мы отвлеклись от темы, вам не кажется? ![]() |