Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- //задание рабочего типа, может быть использован любой целочисленный тип
- typedef signed char Integer;
- //максимальная длина строки с двоичным кодом числа
- #define BUFFER_SIZE 1024
- //принимает на вход число, печатает его в двоичной записи с пробелами между байтами
- void printBinary(Integer x)
- {
- /*i, j - вспомогательные переменные для циклов
- base - вспомогательная переменная, два в какой-то целой степени
- bit - переменная, в которой один бит равен единицы, а остальные - нули,
- служит для "отщепления" очередного бита числа*/
- int i, j;
- int base = 1;
- Integer bit;
- //задаем base значение 2 ^ (n - 1), где n - число бит в числе x
- for (i = 0; i < 8 * sizeof(Integer) - 1; ++i)
- base *= 2;
- //пробегаем по всем разрядам слева направо
- for (i = 0; i < sizeof(Integer); ++i)
- {
- for (j = 0; j < 8; ++j)
- {
- //находим значение очередного бита - 0 или 1
- bit = base & x;
- base /= 2;
- x -= bit;
- //соответственно выводим 0 или 1
- if (bit)
- printf("1");
- else
- printf("0");
- }
- printf(" ");
- }
- printf("\n");
- }
- //циклически сдигаем число x на a байт влево
- Integer leftShift(Integer x, int a)
- {
- /*mask - так называемая маска, в данном случае число вида 11100...0,
- предназначенное для отделения первых a бит числа (в ней a единиц)
- carriage - перенос, первые a бит числа, которые будут перенесены из "левого угла" в "правый угол"
- tail - та часть числа, которая сдвигается без переноса
- base - вспомогательная переменная, два в какой-то целой степени
- a - величина сдвига, т.е. число переносимых разрядов,
- k - число сдвигаемых разрядов без переноса*/
- Integer mask = 0, carriage, tail;
- int base = 1, i, k = 8 * sizeof(Integer) - a;
- //задаем маску так, чтобы в ней было a единиц в начале, а дальше шли нули
- for (i = 0; i < a; ++i)
- {
- mask += base;
- base *= 2;
- }
- for (i = 0; i < k; ++i)
- mask *= 2;
- //определяем перенос, т.е. в числе x все биты после a первых заменяем нулями
- carriage = mask & x;
- //определяем "хвост", это исходное число минус перенос, так как первые a бит у этих двух чисел совпадают
- tail = x - carriage;
- /*сейчас число имеет вид a-битовое число * 2 ^ k (в степени k),
- его нужно привести к виду a-битового числа, т.е. разделить на 2 ^ k*/
- for (i = 0; i < k; ++i)
- carriage >>= 1;//carriage /= 2;
- //теперь сдвигаем ту часть числа, которая сдвигается без переноса на a влево
- for (i = 0; i < a; ++i)
- tail *= 2;
- //теперь осуществляем перенос
- tail += carriage;
- return tail;
- }
- int main()
- {
- /*в a будет записано число бит, на которое нужно сдвинуть число x
- результат сдвига будет записан в переменной y*/
- Integer x, y;
- long z;
- int a;
- printf("Циклический сдвиг влево (%d-bit)", 8 * sizeof(Integer));
- //условие выхода из цикла - введен 0
- do
- {
- //считывание данных
- printf("Введите числа: ");
- scanf("%d %d", &z, &a);
- x = (Integer)z;
- /*если нужно сдвинуть влево на отрицательное число бит, это то же самое, что и
- сдвинуть вправо на такое же по модулю положительное число, и это то же самое, что и
- сдвинуть влево на общее число бит минус модуль этого числа*/
- if (a < 0)
- a = 8 * sizeof(Integer) + a;
- //вывод считанного числа в шестнадцатеричной и двоичной записи
- printf("Вы ввели : %i = %x = ", x, x);
- printBinary(x);
- //определение сдвинутого числа
- y = leftShift(x, a);
- //вывод результата в шестнадцатеричной и двоичной записи
- printf("Результат : %i = %x = ", y, y);
- printBinary(y);
- } while (x != 0);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement