Если бы число имело значение типа Word от 256 до 65535, то эффект был бы тем же, только биты «переезжали» бы в поле длиной 16 бит. Для LongInt поле составит 32 бита. При применении операций shl и shr к отрицательным величинам типов ShortInt, Integer, LongInt освобождаемое слева место заполняется единицами.
- 170 -
Конечно, операции сдвига достаточно специфичны и реально нужны только при обработке битовых последовательностей. Пример их использования был дан на рис. 9.1. Там каждый бит последовательно сдвигается к самому левому краю, стирая тем самым все впереди стоящие биты, а затем возвращается в самую правую позицию, стирая тем самым все стоящие правее его биты. В итоге получаем число, равное 0 или 1, в зависимости от содержимого очередного бита.
Операция shl может заменять умножение целых чисел на степени двойки:
J shl 1 = J*2
J shl 2 = J*4
J shl 3 = J*8
Именно здесь заложена идея и принцип сжатия информации: в одном байте можно уместить два четырехбитовых значения. Тогда понадобится всего 40000 байт, что дает двукратный выигрыш! При этом потери заключаются в необходимости кодирования и декодирования значений. Процедуры преобразования могут иметь вид, показанный на рис. 9.2.
Если бы значения в выборке были целыми и имели диапазон 0..3 (т.е. занимали два бита), то можно было бы в один байт уместить четыре таких значения и т.д. Логика останется той же, изменятся лишь параметры в процедурах преобразования.
К сожалению, подобный подход нельзя применить к вещественным значениям. Единственное, что можно посоветовать — это посмотреть, нужны ли именно вещественные формы хранения данных. Так, если хранится массив вещественных (Real — 6 байт на элемент) значений размеров чего-либо в метрах с точностью до сантиметра, и самое длинное измерение не превосходит 2,55 м, то гораздо эффективнее будет хранить их как массив размеров в сантиметрах. И одно значение будет свободно размещаться в одном байте! Тип Byte занимает 1 байт — экономия шестикратная.
- 171 -
| { Процедура кодирования X1 и X2 в один байт (X1, X2<=15) }
| PROCEDURE Code2to1( X1,X2 : Byte; VAR X1X2 : Byte );
| BEGIN
| X1X2 := X1 + (X2 shl 4 )
| END;
| {Процедура декодирования X1 и X2 из одного байта }
| PROCEDURE DeCode1to2{ X1X2 : Byte; VAR X1,X2 : Byte );
| BEGIN
| X1 := X1X2 and 15; { X1X2 and $F }
| X2 := X1X2 shr 4
| END; VAR {== ПРИМЕР ВЫЗОВА ==}
| C, C1, C2 : Byte;
| BEGIN
| Code2to1(8,7, C);
| WriteLn('8 и 7 - кодируются в —> ',C);
| DeCode1to2(C, C1, C2);
| WriteLn(C:3, — декодируются в --> ',C1:-3,' и ',C2);
| ReadLn { пауза до нажатия клавиши ввода }
| END.
Рис. 9.2
9.3. Логические вычисления и операции отношения
Наличие логического типа Boolean и операций с ним позволяет программировать логические вычисления, причем запись логических выражений будет соответствовать законам Булевой алгебры.
В Турбо Паскале введены четыре логических операции (табл. 9.4, где L1 и L2 — логические константы, переменные или выражения, равные True или False).
Таблица 9.4
Название | Запись | Результат операции | |
not | Логическое 'НЕ' (отрицание) | not A1 | Логическое значение, противоположное значению L1 |
and | Логическое 'И' (конъюнкция) | L1 и L2 | Логическое значение True, если L1 и L2 равны True, и False во всех остальных случаях |
- 172 -