← Назад к вопросам
Как получить число со всеми нулями и единицей в определенном разряде?
2.7 Senior🔥 211 комментариев
#Linux и операционные системы#Qt и GUI#STL контейнеры и алгоритмы
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как получить число со всеми нулями и единицей в определённом разряде
Задача
Получить число, где все биты равны 0, кроме одного бита на позиции n, который равен 1.
Например, для позиции 3 в 8-битном числе результат должен быть: 00001000 (8 в десятичной)
Решение: битовый сдвиг
Простейший способ — сдвинуть единицу на нужную позицию:
#include <iostream>
using namespace std;
int main() {
// Получить число с единицей в позиции 3
int result = 1 << 3; // 1 сдвигаем на 3 позиции влево
cout << result << endl; // Выведет: 8
// В двоичном: 0001 -> 1000
printf("%08b\n", result); // Выведет: 00001000
return 0;
}
Объяснение
Оператор << (левый битовый сдвиг):
x << nозначает: сдвинуть все биты числа x влево на n позиций- Новые позиции справа заполняются нулями
Сдвиг влево на 3:
1 = 0001
1 << 3 = 1000 = 8
Примеры для разных типов данных
#include <cstdint>
#include <iostream>
int main() {
// 8-битное число (unsigned char)
uint8_t bit0 = 1 << 0; // 00000001 = 1
uint8_t bit2 = 1 << 2; // 00000100 = 4
uint8_t bit7 = 1 << 7; // 10000000 = 128
std::cout << "8-bit: " << (int)bit7 << std::endl; // 128
// 16-битное число (unsigned short)
uint16_t bit10 = 1 << 10; // 0000010000000000 = 1024
std::cout << "16-bit: " << bit10 << std::endl; // 1024
// 32-битное число (unsigned int)
uint32_t bit20 = 1u << 20; // Бит в позиции 20
std::cout << "32-bit: " << bit20 << std::endl; // 1048576
// 64-битное число (unsigned long long)
uint64_t bit63 = 1ull << 63; // Старший бит
std::cout << "64-bit: " << bit63 << std::endl;
return 0;
}
Практические применения
1. Установка флага (бита) в числе
// Установить бит n в числе x
uint32_t flags = 0;
int bit_position = 5;
flags |= (1 << bit_position); // Установить бит 5
// flags теперь: xxxxx1xxxx (бит 5 = 1)
2. Проверка флага
// Проверить установлен ли бит n
if ((flags & (1 << 5)) != 0) {
std::cout << "Bit 5 is set" << std::endl;
}
3. Очистка флага
// Очистить бит n
flags &= ~(1 << 5); // Очистить бит 5
// flags теперь: xxxxx0xxxx (бит 5 = 0)
4. Переключение флага
// Переключить бит n (0->1 или 1->0)
flags ^= (1 << 5); // Toggle бит 5
Функция для удобства
#include <cstdint>
// Создать число с единицей в позиции bit_pos
inline uint32_t make_mask(int bit_pos) {
return 1u << bit_pos;
}
// Установить бит
inline uint32_t set_bit(uint32_t value, int bit_pos) {
return value | (1u << bit_pos);
}
// Проверить бит
inline bool test_bit(uint32_t value, int bit_pos) {
return (value & (1u << bit_pos)) != 0;
}
// Очистить бит
inline uint32_t clear_bit(uint32_t value, int bit_pos) {
return value & ~(1u << bit_pos);
}
// Переключить бит
inline uint32_t toggle_bit(uint32_t value, int bit_pos) {
return value ^ (1u << bit_pos);
}
int main() {
uint32_t value = 0;
// Установить биты 3, 5, 7
value = set_bit(value, 3); // 00001000
value = set_bit(value, 5); // 00101000
value = set_bit(value, 7); // 10101000 = 168
std::cout << value << std::endl; // 168
std::cout << test_bit(value, 5) << std::endl; // 1 (true)
std::cout << test_bit(value, 4) << std::endl; // 0 (false)
return 0;
}
Частые ошибки
Ошибка 1: забыть u для unsigned
// ПЛОХО (может быть undefined для больших чисел)
int x = 1 << 31; // Signed shift, UB!
// ХОРОШО
uint32_t x = 1u << 31; // Unsigned shift, safe
Ошибка 2: сдвиг на число, больше чем размер типа
// ПЛОХО: undefined behavior
uint8_t x = 1 << 10; // Сдвиг на 10, но uint8_t только 8 бит
// ХОРОШО: сдвиг в пределах размера типа
uint32_t x = 1u << 10; // OK, uint32_t имеет 32 бита
Ошибка 3: забыть про приоритет операций
// ПЛОХО: & имеет ниже приоритет чем <<
if (x & 1 << 5) { // Интерпретируется как: x & (1 << 5)? Нет!
// Это вычисляет: (x & 1) << 5
}
// ХОРОШО: используй скобки
if (x & (1 << 5)) {
// Это вычисляет: x & (1 << 5)
}
Битовые флаги в реальных проектах
// Пример: регистр CPU состояния с битовыми флагами
class RegisterStatus {
private:
uint32_t value = 0;
public:
// Флаг 0: Zero (результат = 0)
bool is_zero() const { return value & (1 << 0); }
void set_zero() { value |= (1 << 0); }
// Флаг 1: Carry (был перенос)
bool has_carry() const { return value & (1 << 1); }
void set_carry() { value |= (1 << 1); }
// Флаг 2: Overflow (переполнение)
bool has_overflow() const { return value & (1 << 2); }
void set_overflow() { value |= (1 << 2); }
};
Итого
Ответ на вопрос:
uint32_t mask = 1 << n; // n-я позиция, остальное нули
Применение:
- Установить флаг:
x |= (1 << n) - Проверить флаг:
if (x & (1 << n)) - Очистить флаг:
x &= ~(1 << n) - Переключить:
x ^= (1 << n)