Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/307: Рейтинг темы: голосов - 307, средняя оценка - 4.72
1 / 1 / 0
Регистрация: 03.01.2018
Сообщений: 4

Как определить i-й бит числа

23.03.2018, 00:51. Показов 63990. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго врумени суток, не могу ни как сообразить, как определить i-й бит числа. На просторах интернета нашёл такой вот код

C++
1
int bit = (c >> i) & 1
Где с - число, i - номер получаемого бита. Он работает, но проблема в том, что он переворачивает двоичное представление числа, то есть если я хочу узнать 2 бит (считать начинаем с нуля) числа 10 (в двоичной системе соответственно 1010), то он выдаёт 0, а не единицу, соответственно при поиске первого бита выводит 1 хотя должен вывести 0. Помогите пожалуйста довести до ума данную строку
1
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.03.2018, 00:51
Ответы с готовыми решениями:

Определить, на сколько бит различаются два числа
Привет всем у меня такой вапрос ) как узнать на сколько битов различаеться два числа ?? неужели надо переводить в двоичную СМ и...

Нахождение бит мантиссы и бит порядка вещественного числа
В вузе задали написать программу, которая определяет в каких байтах расположена мантисса, а в каких порядок. Условия задачи: тип:single,...

Определить, каких бит (0 или 1) больше в двоичном представлении числа
Напишите программу, в которой необходимо определить, каких бит (0 или 1) больше в двоичном представлении определенного целого значения А.

14
 Аватар для Новичок
1682 / 1098 / 489
Регистрация: 17.07.2012
Сообщений: 5,360
23.03.2018, 01:11
Обычно биты нумеруются справа. Но если вам нужно слева, придется перевернуть число.
C++
1
2
3
int d = 0;
for (; c; c /= 2) d = d * 2 + c % 2;
c = d;
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
23.03.2018, 01:18
Цитата Сообщение от _Naile_ Посмотреть сообщение
i - номер получаемого бита.
Цитата Сообщение от _Naile_ Посмотреть сообщение
есть если я хочу узнать 2 бит
Нумерация битов идёт с 0.

Добавлено через 1 минуту
Цитата Сообщение от Новичок Посмотреть сообщение
Но если вам нужно слева
Скорее всего (предполагаю), ТС нумерует биты с 1.
0
 Аватар для palva
4272 / 2966 / 691
Регистрация: 08.06.2007
Сообщений: 9,915
Записей в блоге: 4
23.03.2018, 02:51
Цитата Сообщение от nd2 Посмотреть сообщение
Скорее всего (предполагаю), ТС нумерует биты с 1.
Похоже, что он считает биты с нуля слева направо, но вдобавок начинает отсчет со старшего единичного бита. В числе десять 1010 у него второй бит равен 1. Что он будет делать с нулевым или отрицательным числом -- непонятно.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.03.2018, 06:14
Цитата Сообщение от _Naile_ Посмотреть сообщение
Где с - число, i - номер получаемого бита. Он работает, но проблема в том, что он переворачивает двоичное представление числа, то есть если я хочу узнать 2 бит (считать начинаем с нуля) числа 10 (в двоичной системе соответственно 1010), то он выдаёт 0, а не единицу,
Проблема в том что лидирующие нули в двоичном представлении никуда не делись и десятка раскроется во что-то вроде 00001010. И если вы хотите читать биты слева направо, у вас сначала попрут именно лидирующие нули. А избавиться от них - задача не самая тривиальная, так как функции нахождения самого старшего (равно как и самого младшего) бита в C++ так и не завезли.
UPD А нет, вру - std::log2 завезли. Вот значит из него свое i вычитайте и получите индекс нужного бита считая справа.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
23.03.2018, 07:23
Лучший ответ Сообщение было отмечено _Naile_ как решение

Решение

Цитата Сообщение от Renji Посмотреть сообщение
так как функции нахождения самого старшего
в большинстве случаев хватит
C++
1
sizeof(c)*8
если конечно не брать экзотические системы, где байт не 8 бит
соответственно
Цитата Сообщение от Renji Посмотреть сообщение
хотите читать биты слева направо,
будет
C++
1
int bit = (c >>(sizeof(c)*8 -i)) & 1;
здесь биты будут считываться "по человечески" начиная с первого
если нужно "по машинному" с нулевого, то
C++
1
int bit = (c >>(sizeof(c)*8 -i-1)) & 1;
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.03.2018, 07:27
Цитата Сообщение от ValeryS Посмотреть сообщение
в большинстве случаев хватит
Не, не, я про Bit Scan Reverse (поиск самого старшего единичного бита) и Bit Scan Forward (поиск самого младшего единичного бита). И то, и то давно реализовано на уровне ассемблера, но вот в C++ с этим туго.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
23.03.2018, 07:44
Цитата Сообщение от Renji Посмотреть сообщение
но вот в C++ с этим туго.
может потому, что нафиг ни кому не нужно
старший бит
C++
1
2
3
for(int i=cizeof(c)-1;i>=0;i--)
  if(c&(1<<i))
     break;
младший
C++
1
2
3
for(int i=0;i<cizeof(c);i++)
  if(c&(1<<i))
     break;
и еще стопитсот вариантов
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.03.2018, 07:53
Цитата Сообщение от ValeryS Посмотреть сообщение
и еще стопитсот вариантов
Только эти варианты либо имеют линейную сложность, либо слишком сложны чтоб каждый раз переписывать их заново. Вот скажем, очевидная оптимизация:
C++
1
2
if(c&0xFF)//выстрелит в 255 случаях из 256
    return table[c&0xFF];
Вы соответствующую табличку каждый раз заново генерировать будете?
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
23.03.2018, 09:12
Цитата Сообщение от Renji Посмотреть сообщение
каждый раз заново генерировать будете?
а че бы нет
но здесь можно и проше оптимизировать, правда кода больше
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int func(unsigned char c)
{
 if(c&0x01)
   return 0;
 if(c&0x02)
   return 1;
 if(c&0x04)
   return 2;
 if(c&0x08)
   return 3;
 if(c&0x10)
   return 4;
 if(c&0x20)
   return 5;
 if(c&0x40)
   return 6;
 if(c&0x80)
   return 7;
return -1;
}
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.03.2018, 10:00
Цитата Сообщение от ValeryS Посмотреть сообщение
но здесь можно и проше оптимизировать, правда кода больше
Тогда уж:
C++
1
2
3
4
5
6
7
8
9
template<unsigned int halfSize=std::numeric_limits<unsigned int>::digits/2>
unsigned int bsf(unsigned int value)
{
    constexpr unsigned int mask=(1<<halfSize)-1;
    return value&mask?
                bsf<halfSize/2>(value&mask):
                halfSize+bsf<halfSize/2>(value>>halfSize);
}
template<>unsigned int bsf<0>(unsigned int ){return 0;}
Но с if(c&0xFF) в начале все равно будет быстрее.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
23.03.2018, 10:30
Цитата Сообщение от Renji Посмотреть сообщение
Но с if(c&0xFF) в начале все равно будет быстрее.
не а
быстрее будет
Цитата Сообщение от Renji Посмотреть сообщение
C++
1
return table[c&0xFF];
ветвления нет, а нулевую ячейку таблицы и так и так заполнять нужно
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.03.2018, 10:44
Цитата Сообщение от ValeryS Посмотреть сообщение
ветвления нет, а нулевую ячейку таблицы и так и так заполнять нужно
Если без ветвления, то работать будет только для одного байта. А так - алгоритм кушает все, в большинстве случаев сохраняя скорость решения по табличке.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
23.03.2018, 11:44
Цитата Сообщение от Renji Посмотреть сообщение
А так - алгоритм кушает все,
покажь
для числа допустим 0x200
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.03.2018, 11:51
Цитата Сообщение от ValeryS Посмотреть сообщение
для числа допустим 0x200
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
template<unsigned int halfSize=std::numeric_limits<unsigned int>::digits/2>
unsigned int bsf(unsigned int value)
{
    static const unsigned char table[256]={255, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
                                           4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
 
    if(value&0xff)//если первый байт не нулевой - ответ по табличке
        return table[value&0xff];
 
    //ну а нет - ищем не нулевой байт бинарным поиском
    constexpr unsigned int mask=(1<<halfSize)-1;
    return value&mask?
                bsf<halfSize/2>(value&mask):
                halfSize+bsf<halfSize/2>(value>>halfSize);
}
template<>unsigned int bsf<0>(unsigned int ){return 0;}
 
int main()
{
    std::cout<<bsf(0x200)<<std::endl;
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.03.2018, 11:51
Помогаю со студенческими работами здесь

Определить разрядность системы (32-бит или 64-бит)
Как из делфи получить разрядность системы 32-бит или 64-бит? 1) Могу такой командой: WinExec('cmd /c chcp 1251 &amp;&amp; systeminfo...

Как удалить один бит из числа?
Как программно сделать то, что на картинке?

Как проверить восьмой бит числа
как проверить восьмой бит числа на 0 либо 1 не зная остальные биты? И можно ли вообще?

Как определить порядок бит в double?
Как определить порядок бит в double?

Как взять 8 бит 32х-битного числа
есть,например, число в двоичке 10101100 00010000 00100001 00110110 как взять любые(указав какие) 8 бит из него,подскажите пожалуйста?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru