| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Центр помощи > [Turbo Pascal] Побитовые операции |
| Автор: Dower 9.2.2010, 10:32 |
| Задача: Циклически сдвинуть двоичные разряды числа на пять позиций влево. Для примера дана программа, задачу надо решить на основе этой пргграммы. |
| Автор: Dancer 9.2.2010, 13:31 | ||
|
| Автор: Dower 9.2.2010, 13:42 |
| Спасибо, работает. |
| Автор: Dower 9.2.2010, 21:24 |
| А можно краткие пояснения кода. |
| Автор: Dower 24.2.2010, 15:43 |
| А можно краткие пояснения кода. Очень надо. |
| Автор: Dancer 25.2.2010, 17:19 |
| function cyclicShiftLeft(number: word; cyclicBitsLeft: byte):word; var mask :Integer; x,y :word; begin cyclicBitsLeft := cyclicBitsLeft mod 16; mask := pow2(16) - pow2(16 - cyclicBitsLeft); x := number and mask; x := x shr (16 - cyclicBitsLeft); y := number shl cyclicBitsLeft; cyclicShiftLeft := y or x; end; Циклически нужно двинуть биты влево, на числах, которые занимают 2 байта (то есть 16 бит). Это делает функция: function cyclicShiftLeft(number: word; cyclicBitsLeft: byte):word; 16 бит взята потому, что такое значение пользовалось для печати значения числа в двоичном виде(код топик_стартера): procedure Print_binary (d: word); 1. Так как циклически двигаются биты в 16 битовом числе, то берём остаток от деления на 16 числа, которое передаются в функцию (cyclicBitsLeft), это число не может быть более 255, так как тип описан как byte. cyclicBitsLeft := cyclicBitsLeft mod 16; Получив остаток от деления, получаем число, на сколько бит действительно нужно будет делать левый сдвиг. 2. Дале получаем маску, по которой вытаскиваем биты, которые у нас цикличиски перейдут в конец получаемого числа. Для этого нам нужно из 2 в степени 16 вычесть число 2 в степени (16 - количество бит, на которе делается левый сдвиг) mask := pow2(16) - pow2(16 - cyclicBitsLeft); 3. Делаем логическое умножение нашего "входного" числа с маской, то есть выделяем те биты, которые после выполнения операции левого сдвига должны будут оказаться вконце нашего результирующего числа (советую порисовать на бумажке представление чисел в двоичной форме и подвигать их самостоятельно) Получаем число: x := number and mask; 4. Далее выполняем правый сдвиг числа x на нужное количество бит (16 - (количество_бит_левого_сдвига mod 16)) то есть, биты слева будут заполнены нулями, а наши битики из числа взятые по маске двигаются в конец числа x. x := x shr (16 - cyclicBitsLeft); 5. Далее нужно подвинуть битики нашего "входного" числа влево, заполняя нулями правые сдвинутые биты. y := number shl cyclicBitsLeft; 6. Тепеть нужно логически сложить числа x и y, чтобы получить результат, и вернуть этот результат из функции. cyclicShiftLeft := y or x; Всё. Ловкость рук и никакого мошенства! Пример: входное число 52, сдвигаем на 11 бит циклически влево. c:= cyclicShiftLeft(a, 11); Запишим число a в двоичном виде (не забываем, что у нас числа 16 битные): 0000000000110100 получаем маску, по которой нужно сохранить число, то есть старшие биты, чтобы их передвинуть в конец результирующего числа. mask=pow2(16) - pow2(16-11)=65536-32=0xFFE0 (в двоичном виде: 1111111111100000) теперь делаем логическое умножение: 0000000000110100 (number) AND 1111111111100000 (mask) ============== 0000000000100000 (x) то есть, x у нас теперь равно 32, или 0x0020: (0000000000100000) теперь передвигаем число x вправо на (16-11) бит это равносильно тому, что мы бы эти биты циклически подвинули влево на 11 бит. x := x shr 5; слева будет заполено нулями, то есть получаем: x = 1, или 0x0001 (0000000000000001) теперь передвигаем "входное" число на 11 бит влево, справа заполняя нулями. y := number shl 11; 0000000000110100 (number) << 11 y = 40960, или 0xA000 (1010000000000000) теперь логически складываем эти два числа: 1010000000000000 (y) OR 0000000000000001 (x) ============== 1010000000000001 (результат) 40961 или 0xA001 |
| Автор: Dower 25.2.2010, 22:24 |
| Огромное вам спасибо |