Страница 1 из 1
Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 14:32:25
coding
Не правильно работает операция смещения либо я чего-то (как я думаю) не знаю.
Есть какая-то функция
Код: Выделить всё
if((0b100010000000000001 &(1<<15))!=0) {
return 1;
} else {
return 0;
}
Как я думаю, функция должна вернуть 0, а возвращает 1 (это на 16-м бите), на 17,18 - возвращает постоянно 0.
Такое чувство, что оно только умеет считать до 16бит. Что я не так делаю?
Всем спасибо.
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 14:49:34
a_skr
а если явно long задать?
if((0b100010000000000001L &(1L<<15))!=0)
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 14:50:09
coding
a_skr писал(а):а если явно long задать?
if((0b100010000000000001L &(1L<<15))!=0)
Явно - это как?
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 14:51:48
__Alexander
coding писал(а):a_skr писал(а):а если явно long задать?
if((0b100010000000000001L &(1L<<15))!=0)
Явно - это как?
Присмотритесь в код. Букву L видите? Вот это и есть явно. По умолчанию, верно замечено, только 16 бит.
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 14:55:58
coding
Да, увидел, после того как отправил.
Уже проверяю.
===
Уже проверил!! Работае. Спасибо оргомное! Тепер буду знать!
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 15:30:14
coding
И еще вопрос, а как программно можно узнать сколько бит в числе?
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 16:13:36
a_skr
определяется типом при объявлении переменной. например long - 32 бита, char - 8 и т.д.
можно sizeof использовать, умноженный на 8, но это не совсем "программно", т.к. вычисляется на этапе компиляции.
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 16:14:15
coding
Понял, спасибо!
Re: Не правильно работает побитовая операция смещения
Добавлено: Пн июл 09, 2012 18:38:01
avreal
a_skr писал(а):определяется типом при объявлении переменной. например long - 32 бита, char - 8 и т.д.
Нужно быть где-то в глубине души готовым к тому, что long может быть и 64 бита. Ну вот придётся писать библиотечку обмена со своим устройством для работы из Linux/64 и по неосторожности получите что-то типа того, что
FTDI подарила (лучше бы уже не трогали, раз промахнулись поначалу).
Или окажется 16 бит, как для avr-gcc с ключиком -mint8 (int становится 8 бит, long -- 16, это отклонение от стандарта и уже не рекомендуется к использованию, но оно есть/было).
char реже скачет, но на некоторых TMS320 он 16-битный (но при этом sizeof(char) == 1 всё равно, так как это «по определению»).
a_skr писал(а):можно sizeof использовать, умноженный на 8, но это не совсем "программно", т.к. вычисляется на этапе компиляции.
Привыкайте не на 8, а на CHAR_BITS -- тогда точно проблем не будет никогда.
Ну и да, кстати, кое-что можно не на этапе компиляции, а на этапе препроцессинга для условной компиляции.
Код: Выделить всё
#include <limits.h> // Тут же и CHAR_BITS определён
И тут куча определений по мин/макс значениям для родных целочисленных типов для данной платформы (контроллер/режим/компилятор). По плавающим -- float.h.
Re: Не правильно работает побитовая операция смещения
Добавлено: Вт июл 10, 2012 08:14:08
a_skr
avreal писал(а):Привыкайте не на 8, а на CHAR_BITS -- тогда точно проблем не будет никогда.
я для себя даже придумать такую ситуацию не могу, где бы это понадобилось

надеюсь, привыкать не придется.
Re: Не правильно работает побитовая операция смещения
Добавлено: Вт июл 10, 2012 19:05:04
YS
Что я не так делаю?
Не читаете мануалы. По умолчанию явно записанные константы в C имеют тип int. А разрядность int надо уточнять в доках на конкретный компилятор.
Нужно быть где-то в глубине души готовым к тому, что long может быть и 64 бита. ... Привыкайте не на 8, а на CHAR_BITS
Я бы предложил привыкать использовать stdint.h и его
intNN_t. Вот там разрядность точно гарантируется.
Re: Не правильно работает побитовая операция смещения
Добавлено: Ср июл 11, 2012 09:40:09
avreal
YS писал(а):Я бы предложил привыкать использовать stdint.h и его intNN_t. Вот там разрядность точно гарантируется.
* Сам давно им пользуюсь.
* До сих пор могут встречаться компиляторы, не имеющие его в поставке (по крайней мере пару лет назад на такое обижались). Оно из С99, а некоторые компиляторы этот стандарт не поддерживают (хотя уж include-файл-то можно было бы добавить).
* Строго говоря, гарантируется не разрядность а поведение. Т.е. на машине с минимально-адресуемой единицей памяти в 16 бит тип uint8_t не сможет занять меньше 16 бит. Но при операциях с ним компилятор будет должен производить маскирование &= 0xFF, чтобы работало как если бы он 8 бит.
Код: Выделить всё
uint8_t i = 255; // займёт одну ячейку памяти в 16 бит
...
i = i + 1; // будет произведено маскирование после инкремента
...
if (i != 0) puts("Всё пропало, шеф!")
Re: Не правильно работает побитовая операция смещения
Добавлено: Ср июл 11, 2012 18:20:55
YS
Строго говоря, гарантируется не разрядность а поведение.
Это понятно. Но, если не играться с указателями, то ничего не сломается, потому что компилятор понимает, что от такой переменной ждут восьмибитного поведения.