Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Переменная, как набор битов.

61K
09 апреля 2011 года
kolob2000
13 / / 15.10.2010
Привет!
Подскажите каким образом
можно в целочисленной
переменной обращаться,
как к двоичному числу, к
каждому биту отдельно.
Примерно так же, как к
элементам массива.
Заранее спасибо.
535
09 апреля 2011 года
Нездешний
537 / / 17.01.2008
С++
1. Можете использовать битовые поля
Код:
union BitFieldsTest
{
    unsigned char Byte;
#pragma pack(1)
    struct
    {
        bool Bit0: 1;
        bool Bit1: 1;
        bool Bit2: 1;
        bool Bit3: 1;
        bool Bit4: 1;
        bool Bit5: 1;
        bool Bit6: 1;
        bool Bit7: 1;
    };
#pragma pack()
};

//использование
BitFieldsTest u;
u.Byte = your_value;
cout << u.Bit4 << endl;


2. Еще вариант - std::bitset
 
Код:
#include <bitset>

std::bitset< sizeof(your_value) * 8 > bs(your_value);
cout << bs[4] << endl;
61K
09 апреля 2011 года
kolob2000
13 / / 15.10.2010
Цитата: Нездешний
С++
1. Можете использовать битовые поля
Код:
union BitFieldsTest
{
unsigned char Byte;
#pragma pack(1)
struct
{
bool Bit0: 1;
bool Bit1: 1;
bool Bit2: 1;
bool Bit3: 1;
bool Bit4: 1;
bool Bit5: 1;
bool Bit6: 1;
bool Bit7: 1;
};
#pragma pack()
};

//использование
BitFieldsTest u;
u.Byte = your_value;
cout << u.Bit4 << endl;


2. Еще вариант - std::bitset
 
Код:
#include <bitset>

std::bitset< sizeof(your_value) * 8 > bs(your_value);
cout << bs[4] << endl;





Спасибо конечно, но это не совсем то, что мне надо. Мне нужно объявить двойное слово и в генерировать в нём в каждый нужный момент случайное значение. Но мне нужно не его десятичное значение, а его двоичная форма. Мне важен каждый бит. В каждый нужный мне момент мне нужен или ноль, или еденица по каждому биту. Нужно случайное количество этих самых значений, а с битовой маской так не выдет.

7
09 апреля 2011 года
@pixo $oft
3.4K / / 20.09.2006
Ну а пройтись по всем битам не судьба?Или конвертируйте тогда в строку,содержащую двоичное представление числа

[COLOR="#808080"]P.S.Что за странная манера писать посты как стихи–уписывая их в узкий-узкий столбец?[/COLOR]
61K
09 апреля 2011 года
kolob2000
13 / / 15.10.2010
Цитата: @pixo $oft
Ну а пройтись по всем битам не судьба?Или конвертируйте тогда в строку,содержащую двоичное представление числа

[COLOR="#808080"]P.S.Что за странная манера писать посты как стихи–уписывая их в узкий-узкий столбец?[/COLOR]



А со стоками это интересно, точнее с-сроки. Спасибо, как то даже не подумал об этом.
А за манеру письма в посте извините. С телефона пишу видно потому и получается таким.

7
09 апреля 2011 года
@pixo $oft
3.4K / / 20.09.2006
И всё же я не понимаю,чем не устраивают приведённые выше способы…
360
09 апреля 2011 года
P*t*
474 / / 15.02.2007
2@pixo$oft

Человек хочет что-то такое:
 
Код:
bool read(int v, int bit) {
   return (v>>bit) & 1;
}
void write(int& v, int bit, bool value) {
   if (value)
      v |= (1<<bit);
   else
      v &= ~(1<<bit)
}
260
09 апреля 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: P*t*
2@pixo$oft

Человек хочет что-то такое:
 
Код:
bool read(int v, int bit) {
   return (v>>bit) & 1;
}
void write(int& v, int bit, bool value) {
   if (value)
      v |= (1<<bit);
   else
      v &= ~(1<<bit)
}



Отличный пример того как писать не следует.

360
09 апреля 2011 года
P*t*
474 / / 15.02.2007
Цитата: Ramon
Отличный пример того как писать не следует.



Почему?
Я иногда такое использовал в олимпиадных задачах. Разве что для ускорения работы программы не делал для этих операций отдельных функций.

61K
10 апреля 2011 года
kolob2000
13 / / 15.10.2010
А не подходит потому, что с отдельными битами в этих логических операциях процессорное время дорого. Программа по результату каждого бита будет прорисовывать ту или иную текстуру. А их там, достаточно много, нужен оптимум.
61K
10 апреля 2011 года
kolob2000
13 / / 15.10.2010
Я вообще, думаю этот кусок кода на асме написать, там всё на много проще.
260
10 апреля 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: kolob2000
Я вообще, думаю этот кусок кода на асме написать, там всё на много проще.



Вы будете удивлены написав сие на ассемблере да так и не получив ожидаемой "скорости".

260
10 апреля 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: P*t*
Почему?
Я иногда такое использовал в олимпиадных задачах. Разве что для ускорения работы программы не делал для этих операций отдельных функций.



Как минимум, радость от сего кода на граничных условиях будет особенно хороша и не предсказуема ибо читаем стандарт.

360
10 апреля 2011 года
P*t*
474 / / 15.02.2007
Я вас не понял. Можно подробнее?
Какие граничные условия? Ноль? Отрицательные числа? Имеется в виду, что у отрицательных чисел после сдвига в старший бит записывается 1? Но в данном случае это не может никак помешать.

Битовые операции - одни из наиболее быстрых операций. Работать это должно быстрее, чем обычное обращение к массиву.
Я полагаю, что если откомпилировать вариант Нездешнего и посмотреть ассемблерное представление, то окажется, что реализуется оно опять же через битовые сдвиги.
61K
10 апреля 2011 года
kolob2000
13 / / 15.10.2010
Цитата: P*t*
Я вас не понял. Можно подробнее?
Какие граничные условия? Ноль? Отрицательные числа? Имеется в виду, что у отрицательных чисел после сдвига в старший бит записывается 1? Но в данном случае это не может никак помешать.

Битовые операции - одни из наиболее быстрых операций. Работать это должно быстрее, чем обычное обращение к массиву.
Я полагаю, что если откомпилировать вариант Нездешнего и посмотреть ассемблерное представление, то окажется, что реализуется оно опять же через битовые сдвиги.



Да согласен битовые операции наиболее быстрые, но опять же в асме. Они и используются в нём вместо операции умножения и выполняются на несколько порядков быстрей. А в языках высокого уровня компилятор создаёт избыточный код при работе с отдельными битами и из-за этого они теряют свою скорость. Он и придуман чтоб облегчить жизнь программисту, чтобы он не тратил своё время на такты а работал с готовыми функциями и объектами. И дело тут вовсе не в ноле и не в отрицательных числах, да и разницы вовсе нет отрицательное оно или положительное.

360
10 апреля 2011 года
P*t*
474 / / 15.02.2007
Цитата: kolob2000
Да согласен битовые операции наиболее быстрые, но опять же в асме. Они и используются в нём вместо операции умножения и выполняются на несколько порядков быстрей. А в языках высокого уровня компилятор создаёт избыточный код при работе с отдельными битами и из-за этого они теряют свою скорость. Он и придуман чтоб облегчить жизнь программисту, чтобы он не тратил своё время на такты а работал с готовыми функциями и объектами. И дело тут вовсе не в ноле и не в отрицательных числах, да и разницы вовсе нет отрицательное оно или положительное.



Берем кусочек кода на Си:

 
Код:
int a, b, c;
a = (b<<c)&1;


Компилируем и смотрим, что получилось:
 
Код:
movl    -12(%rbp), %eax // вытаскивается в регистр "c"
    movl    -16(%rbp), %edx // вытаскивается в регистр "b"
    movl    %edx, %ebx
    .cfi_offset 3, -24
    movl    %eax, %ecx
    sall    %cl, %ebx          // битовый сдвиг
    movl    %ebx, %eax
    andl    $1, %eax           // битовое И
    movl    %eax, -20(%rbp) // результат пихается в "a"


Битовая операция Си транслируется в одну команду процессору.
И где вы тут видите избыточный код, на порядок замедляющий битовые операции?
61K
10 апреля 2011 года
kolob2000
13 / / 15.10.2010
Извиняюсь, согласен. Это я уже туплю сижу. Вот же оно:

bool read
(int v,
int bit)
{
return
(v>>bit)
& 1;
}
только в цикл надо вставить А я сижу за битовые поля рассказываю.
Устал уже наверно, уже третий день все эти пертурбации на бумаге считаю. Проверить не где, до компа только завтра доберусь.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог