Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

Не правильно работает побитовая операция смещения

Пн июл 09, 2012 14:32:25

Не правильно работает операция смещения либо я чего-то (как я думаю) не знаю.
Есть какая-то функция
Код:
     if((0b100010000000000001 &(1<<15))!=0) {
         return 1;
     } else {
            return 0;
     }


Как я думаю, функция должна вернуть 0, а возвращает 1 (это на 16-м бите), на 17,18 - возвращает постоянно 0.
Такое чувство, что оно только умеет считать до 16бит. Что я не так делаю?
Всем спасибо.

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 14:49:34

а если явно long задать?
if((0b100010000000000001L &(1L<<15))!=0)

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 14:50:09

a_skr писал(а):а если явно long задать?
if((0b100010000000000001L &(1L<<15))!=0)


Явно - это как?

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 14:51:48

coding писал(а):
a_skr писал(а):а если явно long задать?
if((0b100010000000000001L &(1L<<15))!=0)


Явно - это как?


Присмотритесь в код. Букву L видите? Вот это и есть явно. По умолчанию, верно замечено, только 16 бит.

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 14:55:58

Да, увидел, после того как отправил.
Уже проверяю.
===
Уже проверил!! Работае. Спасибо оргомное! Тепер буду знать!

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 15:30:14

И еще вопрос, а как программно можно узнать сколько бит в числе?

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 16:13:36

определяется типом при объявлении переменной. например long - 32 бита, char - 8 и т.д.
можно sizeof использовать, умноженный на 8, но это не совсем "программно", т.к. вычисляется на этапе компиляции.
Последний раз редактировалось a_skr Пн июл 09, 2012 16:15:35, всего редактировалось 1 раз.

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 16:14:15

Понял, спасибо!

Re: Не правильно работает побитовая операция смещения

Пн июл 09, 2012 18:38:01

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

avreal писал(а):Привыкайте не на 8, а на CHAR_BITS -- тогда точно проблем не будет никогда.
я для себя даже придумать такую ситуацию не могу, где бы это понадобилось ;) надеюсь, привыкать не придется.

Re: Не правильно работает побитовая операция смещения

Вт июл 10, 2012 19:05:04

Что я не так делаю?


Не читаете мануалы. По умолчанию явно записанные константы в C имеют тип int. А разрядность int надо уточнять в доках на конкретный компилятор.

Нужно быть где-то в глубине души готовым к тому, что long может быть и 64 бита. ... Привыкайте не на 8, а на CHAR_BITS


Я бы предложил привыкать использовать stdint.h и его [u]intNN_t. Вот там разрядность точно гарантируется.

Re: Не правильно работает побитовая операция смещения

Ср июл 11, 2012 09:40:09

YS писал(а):Я бы предложил привыкать использовать stdint.h и его [u]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

Строго говоря, гарантируется не разрядность а поведение.


Это понятно. Но, если не играться с указателями, то ничего не сломается, потому что компилятор понимает, что от такой переменной ждут восьмибитного поведения.
Тема закрыта