Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/30: Рейтинг темы: голосов - 30, средняя оценка - 4.80
1 / 1 / 0
Регистрация: 10.04.2016
Сообщений: 29
1

Битовое сравнение чисел

10.04.2016, 17:38. Просмотров 5731. Ответов 19
Метки нет (Все метки)

Создать функцию которая возвращает число, полученное из побитового сравнения трех заданных чисел за следующим образом, если на однаковой позиции у всех чисел размещены одинаковые биты то в новом числе на этой позиции будет размещен 1 бит, иначе 0 бит.все это сделать с помощью побитовых операций.
Например: x=5; y=6; z=7; то должно вивесты число d=4, потому что в двоичной системе 5=101,6=110,7=111
Помогите пожалуйста, очень нужно !
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.04.2016, 17:38
Ответы с готовыми решениями:

Имеется массив из n чисел от 0 до (2 в степени k) - 1, каждое из которых мы будем рассматривать как k-битовое слово. Используя проверки "i-ый бит рав
помогите, пожалуйста, решить задачку. Имеется массив из n чисел от 0 до (2 в степени k) - 1,...

Поиск чисел в строках и сравнение этих чисел
Здравствуйте. Помогите пожалуйста с задачей: есть файл, в нём несколько строк. В каждой строке...

Битовое И
Добрый день. Изучаю битовые операции, в частности битовое И. Вот в чём вопрос: 3 & 8 = 0, т.к. ...

Битовое представление
Здравствуйте! Напишите пример функции, которая принимает целое число и выводит его битовое...

19
Падаван С++
443 / 257 / 88
Регистрация: 11.11.2014
Сообщений: 897
10.04.2016, 17:49 2
Torotorkina,
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int func(int x, int y, int z) {
    return x & y & z;
}
int main(int argc, char* argv[]) {
    std::cout << func(5, 6, 7);
    std::cin.ignore();
    return 0;
}
P.S мой совет подучить вам что такое битовое и, или, исключающее или, а именно их таблицы истинности, и посмотреть как их использовать для чисел в с++
0
1 / 1 / 0
Регистрация: 10.04.2016
Сообщений: 29
10.04.2016, 17:55  [ТС] 3
Это все нужно записать в одну функцию и в int main () должно лишь выводить новое число
0
Падаван С++
443 / 257 / 88
Регистрация: 11.11.2014
Сообщений: 897
10.04.2016, 18:04 4
Torotorkina, а здесь что не так, 1 функция которая возвращает значение, вы похоже совсем с программированием не знакомы
ну пишите так
C++
1
int d = func(5, 6, 7);
или так
C++
1
int d = 5 & 6 & 7;
или если вам угодно не числа передавайте а переменные
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
int func(int x, int y, int z) {
    return x & y & z;
}
int main(int argc, char* argv[]) {
    setlocale(LC_ALL, "Russian");
 
    int x, y, z;
    std::cout << "Введите х : ";
    std::cin >> x;
    std::cout << "Введите y : ";
    std::cin >> y;
    std::cout << "Введите z : ";
    std::cin >> z;
 
    std::cout << func(x, y, z);
    std::cin.ignore();
    return 0;
Если надо чтобы функция не возвращала значение а в ней же выводила то вот
C++
1
2
3
4
void func(int x, int y, int z) {
    int tmp = x & y & z;
    std::cout << tmp << std::endl;
}
Добавлено через 2 минуты
Вам дали решение проблеммы, но вы даже не понимаеме как вывести значение на экран в функции или вне, тут решение это как получить ответ а не вывести его на экран
0
1 / 1 / 0
Регистрация: 10.04.2016
Сообщений: 29
10.04.2016, 18:07  [ТС] 5
Я понимаю как вывести его на екран и как работает функция, но это задание можно сделать как то по другому, ибо мы только начинаем изучать программирование.
Я очень благодарна что вы помогли мне с решением дачного задания.
0
Падаван С++
443 / 257 / 88
Регистрация: 11.11.2014
Сообщений: 897
10.04.2016, 18:10 6
Torotorkina,
Цитата Сообщение от Torotorkina Посмотреть сообщение
Создать функцию которая возвращает число, полученное из побитового сравнения трех заданных чисел за следующим образом
, битовое И делает побитовое сравнение числа, вот его таблица истинности
x1 x2| y
_______
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
это самое легкое решение задачи
Если хотите по другому то вот вам идея, сдвигайтесь по 1 биту и запоминайте когда были единицы, так пройтись по трем числам, запомнить еденицы в массив, можно типа bool, после этого сделать функцию преобразования числа из массива булов в 10ричное число, ну и сравнением полей 3х массивов получить 4й который будет результатом, естественного его в число и преобразовавывать, это вам идея если запись решения вашей проблеммы в 1 строку слишком сложная
0
1 / 1 / 0
Регистрация: 10.04.2016
Сообщений: 29
10.04.2016, 18:13  [ТС] 7
но когда мы например введем числа 4,4,6, то в результате мы получим не 5 в результате, а 4.
0
Падаван С++
443 / 257 / 88
Регистрация: 11.11.2014
Сообщений: 897
10.04.2016, 18:16 8
Torotorkina, угу я наверное считать не умею, как же мы это из 4, 4, 6 получим 5, когда
4 = 100
4 = 100
6 = 110
0
Падаван С++
443 / 257 / 88
Регистрация: 11.11.2014
Сообщений: 897
10.04.2016, 18:19 9
Вот
0
Миниатюры
Битовое сравнение чисел  
1 / 1 / 0
Регистрация: 10.04.2016
Сообщений: 29
10.04.2016, 18:20  [ТС] 10
а вот так
4=100
4=100
6=110
и что у нас получается, на первой позиции у нас все 1 значит в новом числе это тоже будет 1, дальше у нас идут 0,0 и 1 они разные, тобиш у нас будет 0 в новом числе на 2 позиции, и в самом конце у нас опять идет совпадение всех битов, а именно 0,0,0 и тогда у нас должно получится число 101, то есть 5

Добавлено через 43 секунды
для решения этой задачи побитового И будет маловато
0
112 / 103 / 50
Регистрация: 29.03.2016
Сообщений: 468
10.04.2016, 18:41 11
Torotorkina, очень сильно ошибаетесь. тип int это 32 бита
0000 0000 0000 0100
0000 0000 0000 0100
0000 0000 0000 0110
результат:
1111 1111 1111 1101
0
1 / 1 / 0
Регистрация: 10.04.2016
Сообщений: 29
10.04.2016, 18:45  [ТС] 12
Цитата Сообщение от obivan Посмотреть сообщение
0 0 | 0
вы выше сами писали какой результат дает побитовое И когда сравнивать 0, но почему то сдесь у вас уже они равни 1
Цитата Сообщение от Serg_o_Grey Посмотреть сообщение
0000 0000 0000 0100
0000 0000 0000 0100
0000 0000 0000 0110
результат:
1111 1111 1111 1101
Почему так то ?

Добавлено через 2 минуты
Цитата Сообщение от Serg_o_Grey Посмотреть сообщение
0000 0000 0000 0100
0000 0000 0000 0100
0000 0000 0000 0110
результат:
1111 1111 1111 1101
и в итоге у нас должно вийти 5
0
112 / 103 / 50
Регистрация: 29.03.2016
Сообщений: 468
10.04.2016, 18:56 13
Torotorkina, это не я писал. а тот кто писал относительно операции 'И' был прав
я для вашей операции привел пример, и того что Вы утверждали, что данная схема дает 5
0
1 / 1 / 0
Регистрация: 10.04.2016
Сообщений: 29
10.04.2016, 18:57  [ТС] 14
я уже понела, просто проблема в том что бы правильно вывести этот результат
0
112 / 103 / 50
Регистрация: 29.03.2016
Сообщений: 468
10.04.2016, 18:58 15
432
0
Падаван С++
443 / 257 / 88
Регистрация: 11.11.2014
Сообщений: 897
10.04.2016, 19:05 16
Torotorkina, я понял что вы хотите, и чтобы нули типо учитывались, но если вам такое нужно, то Serg_o_Grey, прав, у вас остается 28 бит нулей при данных числах, и они станут еденицами, но если вам именно так и надо(но 5 вы не получите), то вот таблица истинности XOR
x1 x2 | y
________
0 0 0
0 1 1
1 0 1
1 1 0
Она противоположенна тому чего вы хотите, вам нужно сделать инверсию значений XOR и тогда вы получите ваш результат (но еще раз, 5 там не будет)
P.S лично мне кажется что вы не правильно поняли задание, и с нулями работать не нужно так как вы описали

Добавлено через 3 минуты
Torotorkina, и даже вам привели не 32 битовый инт а 16 битовый (short) при инте у вас значение за миллиард залезет если так как вы хотите
0
Эксперт С++
3206 / 1733 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
10.04.2016, 19:14 17
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <bitset>
#include <iostream>
/////////////////////////////////////////////////////////////////////////////////////////
const   size_t  ARGS_COUNT  =   3;
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::bitset<ARGS_COUNT>     T_args_bitset;
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    for( size_t i{}; i < 1U << ARGS_COUNT; ++i )
    {
        T_args_bitset  b{i};
 
        std::cout   <<  b.to_string()
                    <<  " -> "
                    <<  !( b[0]^b[1] | b[1]^b[2] )
                    <<  std::endl;
    }
}
0
С чаем беда...
Эксперт CЭксперт С++
8042 / 3930 / 1085
Регистрация: 18.10.2014
Сообщений: 8,455
10.04.2016, 20:26 18
Лучший ответ Сообщение было отмечено Torotorkina как решение

Решение

Цитата Сообщение от obivan Посмотреть сообщение
то Serg_o_Grey, прав, у вас остается 28 бит нулей при данных числах
Я думаю не надо быть семи пядей во лбу, чтобы догадаться, что в задаче подразумевается, что ширина результата должна быть равна позиции самого старшего бита в максимальном входном значении. (Полагая, что три нуля - запрещенный вход или правильный результат для трех нулей - 0.)

Поэтому от ширины типа int, short или еще чего-то в этом роде решение данной задачи не зависит

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsigned bit_compare(unsigned a, unsigned b, unsigned c)
{
  unsigned result = 0;
  unsigned limit = a | b | c;
 
  for (unsigned mask = 1; mask > 0 && mask <= limit; mask <<= 1)
  {
    unsigned old_bit_a = a & mask, old_bit_b = b & mask, old_bit_c = c & mask;
    if (old_bit_a == old_bit_b && old_bit_b == old_bit_c)
      result = result | mask;
  }
 
  return result;
}
От ветвления внутри цикла можно избавиться (похитив булевское выражение у Mr.X,)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsigned bit_compare(unsigned a, unsigned b, unsigned c)
{
  unsigned result = 0;
  unsigned limit = a | b | c;
 
  for (unsigned mask = 1; mask > 0 && mask <= limit; mask <<= 1)
  {
    unsigned old_bit_a = a & mask, old_bit_b = b & mask, old_bit_c = c & mask;
    unsigned new_bit = ~((old_bit_a ^ old_bit_b) | (old_bit_b ^ old_bit_c)) & mask;
    result |= new_bit;
  }
 
  return result;
}
Добавлено через 10 минут
Понятно, что эти битовые операции можно выполнять "параллельно" над всеми битами одновременно. Но тогда для игнорирования ненужных старших битов надо уметь быстро определять номер старшего единичного бита. Не вдаваясь эти дебри, можно предложить такой вариант

C++
1
2
3
4
5
6
7
8
9
10
unsigned bit_compare(unsigned a, unsigned b, unsigned c)
{
  unsigned mask = a | b | c;
 
  do
    mask |= (mask >> 1);
  while (((mask + 1) & mask) != 0);
 
  return ~((a ^ b) | (b ^ c)) & mask;
}
1
Падаван С++
443 / 257 / 88
Регистрация: 11.11.2014
Сообщений: 897
10.04.2016, 20:29 19
TheCalligrapher, можно комент вот сюда ?
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
do
* * mask |= (mask >> 1);
* while (((mask + 1) & mask) != 0);
0
С чаем беда...
Эксперт CЭксперт С++
8042 / 3930 / 1085
Регистрация: 18.10.2014
Сообщений: 8,455
10.04.2016, 21:16 20
Цитата Сообщение от obivan Посмотреть сообщение
можно комент вот сюда ?
Если забыть о переполнениях, то выражение x & (x + 1) может равняться нулю только в одном случае: если число x имеет вид 00...011...1, т.е. состоит из непрерывной последовательности единиц в правой части. В этом случае x + 1 будет иметь вид 00...100...0 и операция & даст в результате 0. В остальных случаях результат будет ненулевым.

Этот битовый трюк широко используется для распознания чисел вида 2n (единственный единичный бит): x & (x - 1) == 0. И для распознания чисел вида 2n-1 (вереница единиц справа): x & (x + 1) == 0.

В нашем случае я хочу взять результат mask = a | b | c и превратить его в битовую маску, состоящую из сплошных единиц начиная со старшего единичного бита mask и вправо до упора. Для этого я могу просто напросто итеративно "размазывать" все единичные биты mask на один шаг вправо - mask |= (mask >> 1) - до тех пор пока mask не приобретет требуемый вид, что проверяется через ((mask + 1) & mask) == 0.

Этого же самого результата можно было добиться более "тупым" (и, скорее всего, более эффективным) способом

C++
1
2
3
4
5
6
unsigned mask = a | b | c;
mask |= (mask >> 1);
mask |= (mask >> 2);
mask |= (mask >> 4);
mask |= (mask >> 8);
mask |= (mask >> 16);
т.е. путем последовательного "размазывания" единичных битов вправо с постоянно удваивающимся шагом, но такая развертка завязана на ширину типа unsigned, а мне не хотелось на нее завязываться.

Ну и, опять же, если вы умеете быстро вычислять индекс старшего единичного бита в значении, т.е. умеете быстро вычислять log2(x) с округлением вниз, то вся функция может быть реализована как

C++
1
2
3
4
5
unsigned bit_compare(unsigned a, unsigned b, unsigned c)
{
  unsigned mask = (1u << (fast_log2(a | b | c) + 1)) - 1;
  return ~((a ^ b) | (b ^ c)) & mask;
}
Современные процессоры обычно содержат специальную инструкцию для вычисления индекса старшего единичного бита.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.04.2016, 21:16

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Битовое обращение
Здравствуйте. Подскажите пожалуйста, как проще всего обращаться к отдельным битам числа. Для...

Битовое ИЛИ
Есть во многих API такая тема, когда передают в функцию несколько значений в один параметр...

Битовое поле
Здравствуйте! Подскажите, как и что делать с 0x14B5C731+13*9641 and 0xFFFFFFFF. Какое значение...

Битовое представление
Как можно получить любой файл в виде массива бит (именно бит, не байт) чтобы произвести...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.