Задача: Даны два числа — 16 и 2. Напишите программу на C#, которая, используя операции сдвига влево (<<
), сдвига вправо (>>
), а также сложение или вычитание над представленными числами получает итоговый результат равный 127.
Алгоритм решения
Для решения этой задачи нам необходимо вспомнить, что осуществляет сдвиг влево (<<) и сдвиг вправо (>>). Сдвиг влево на 1 разряд — умножает число на 2, сдвиг вправо на 1 разряд — делит число на 2. То есть, если мы рассматриваем сдвиг влево, то :
(1<<7) = (1 * 2 * 2 * 2 * 2 * 2 * 2 *2) = (1*2
7
)= 128
если мы рассматриваем сдвиг вправо:
(128>>7) = (128/2/2/2/2/2/2/2) = (128/2
7
) = 1
Как можно видеть по примерам выше, при любом сдвиге мы оперируем некоторыми числами, которые являются степенями двойки — на это число умножается или делится левый операнд в выражении.
Теперь посмотрим на числа, который нам даны: 16 и 2. Эти числа также являются степенями двойки, так как:
2
4
= 16
2
1
= 2
Ответим на вопрос: как оперируя числами, которые являются степенями двойки получить число 127? Ответ лежит в плоскости математики:
27 — 20 = 128 — 1 = 127
Теперь вернемся к нашим исходным числам. Как из 16 получить 128, используя степени двойки?
16 * 23 =24 * 23 = 128
В данном случае нам достаточно сдвинуть 16 на 3 бита влево, чтобы получить 128.
Как получить из 2 число 1? Также просто — поделить на 2:
2 / 21 = 1
Чтобы поделить число на 2 мы должны сделать сдвиг вправо на 1 бит.
В итоге, мы приходим к готовому решению задачи:
(16 * 23)- (2 / 21) = 127
зеленым цветом выделены исходные числа, красным — количество разрядов для сдвига влево/вправо. Осталось описать это решение на языке C#.
Решение лабораторной работы
Создадим новое консольное приложение в Visual Studio и напишем следующий код:
/* Код взят с сайта http://csharp.webdelphi.ru */ namespace HelloWorld { internal class Program { static void Main(string[] args) { int a = 16;//первое число, которое будем сдвигать влево int b = 2; //второе число, которое будем сдвигать вправо int result = (a << 3) - (b >> 1); //рассчитываем результат Console.WriteLine($"({a} << 3) - ({b} >> 1) = {result}"); } } }
в переменной result
будет находится требуемый результат. После запуска приложения в консоли вы увидите следующий вывод:
Итого
Для решения этой лабораторной работы нам потребовалось вспомнить работу побитовых сдвигов влево и право, а также немного простейшей математики — степени двойки до 128.