Циклический сдвиг разрядов числа - C (СИ)
Формулировка задачи:
Здравствуйте, у меня есть программа
вы не могли бы помочь, объяснить часть программы:
/* ЗАДАНИЕ
Выполнить циклический сдвиг в заданную пользователем сторону на некоторое
количество разрядов в пределах определённой группы разрядов, количество
которых и номер младшего разряда в группе задаются с клавиатуры.
Для unsiged int.
*/
//подключение библиотек
#include <conio.h>
#include <stdio.h>
#include <conio.h>
//главная функция
void main()
{
unsigned int num; //данное число
int low, count; //номер младшего разряда, количество разрядов группы
int side, dist; //сторона сдвига, кол-во разрядов сдвига
int i; //номер разряда
unsigned int result; //результат - число
//выводим заголовок, вводим данные
clrscr();
printf("ПРОГРАММА ВЫПОЛНЯЕТ ЦИКЛИЧЕСКИЙ СДВИГ.\n");
printf("\n");
printf("Введите число типа unsigned int: ");
scanf("%u",&num);
do{
printf("Введите номер младшего разряда в группе (0..15): ");
scanf("%u",&low);
}while(low>15);
do{
printf("Введите количество разрядов группы (0..16): ");
scanf("%u",&count);
}while(low+count>16);
do{
printf("Выберите сторону: 1-влево, 2-вправо. ");
scanf("%u",&side);
}while(side!=1&&side!=2);
do{
printf("Введите количество разрядов сдвига (0..16): ");
scanf("%u",&dist);
}while(dist>16);
//сдвиг вправо - это сдвиг влево на остальное количество разрядов
if(side==2) dist=count-dist;
printf("\n");
//выводим все разряды числа
printf("Число в двоичном виде: \t");
for(i=15; i>=0; i--)
printf("%u",(num>>i)&1);
printf("\n");
//обнуляем результат
result=0;
//цикл для каждого разряда исходного числа
for(i=0; i<=15; i++){
//номер разряда в результате
int k=i;
//если разряд входит в группу
if(i>=low && i<low+count)
//вычисляем новое место разряда в результате сдвига
k=(((i-low)+dist)%count)+low;
//если значение разряда = 1, то прибавляем новое значение к результату
if(num&(1<<i))
result+=(1<<k);
}
//выводим все разряды результата
printf("Результат в двоичном виде: \t");
for(i=15; i>=0; i--)
printf("%u",(result>>i)&1);
printf("\n");
//выводим результат как число, ждём нажатие клавиши
printf("Результат: %u.\n",result);
getch();
}//обнуляем результат
result=0;
//цикл для каждого разряда исходного числа
for(i=0; i<=15; i++){
//номер разряда в результате
int k=i;
//если разряд входит в группу
if(i>=low && i<low+count)
//вычисляем новое место разряда в результате сдвига
k=(((i-low)+dist)%count)+low;
//если значение разряда = 1, то прибавляем новое значение к результату
if(num&(1<<i))
result+=(1<<k);
}Решение задачи: «Циклический сдвиг разрядов числа»
textual
Листинг программы
typedef unsigned long ULI;
/**
* @brief This function is cyclically shift to the left
* @param [in] Number which will be shifted
* @param [in] on some bits
* @return ULI (unsigned long int)
*/
ULI ShiftLeft(const ULI number, const short digit)
{
return
( (number<<digit) |
(number>>( (sizeof(ULI)<<3) - digit) ) );
}
Объяснение кода листинга программы
В данном коде реализована функция ShiftLeft, которая выполняет циклический сдвиг числа на заданное количество бит.
- Тип данных ULI определен как unsigned long int, т.е. 32-битное беззнаковое целое число.
- Входные параметры функции:
- number - число, которое будет сдвинуто (смещение от начала числа)
- digit - количество бит, на которое будет выполнен сдвиг
- В функции используется операция сдвига на число бит, определяемое как (sizeof(ULI)<<3) - digit. Это выражение вычисляет размер числа ULI в байтах (32-битное число занимает 4 байта), затем сдвигает его на 3 байта вправо (чтобы получить количество бит) и вычитает значение digit.
- Результатом работы функции является число, полученное путем сдвига входного числа на digit бит влево и последующего объединения с оставшимися битами исходного числа.