Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
delphi / песни о паскале.pdf
Скачиваний:
63
Добавлен:
26.03.2016
Размер:
5.16 Mб
Скачать

Глава 48 Железная логика

Разбираясь с двоичной системой, мы заглянули внутрь компьютера и обнаружили там регистры, что хранят и обрабатывают числа.

Два взгляда на компьютерные «кирпичики»

Регистры построены из триггеров — элементарных ячеек памяти, способных хранить один бит информации. В регистре может быть 8, 16, 32 или 64 триггера, что соответствует 1, 2, 4 или 8 байтам. Так видят устройство компьютера инженеры-электроники.

А программисты? Они видят то же самое, только называют иначе (рис. 108). То, что электроники именуют триггерами, программисты называют битами, а регистры нам видны как байты, слова и т.д. Так, в Паскале 8-битовый регистр соответствует типу Byte, 16-битовый — типу Word, а 32-битовый — типу

Longint.

Я утверждал, что простые типы данных, такие как числа и символы, неделимы. Теперь признаюсь, что это не совсем так, поскольку в регистре процессора они представлены совокупностью битов. Процессор может работать не только с регистром в целом, но и с отдельными его битами. Иногда эту способность процессора используют и программисты, для чего Паскаль дает им надлежащие средства. Сейчас мы рассмотрим их.

Триггер

Бит

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Инженер-электроник

 

Инженер-программист

 

 

 

 

 

Регистр

 

Байт, Слово и т.д.

Рис. 108 – Устройство процессора глазами электроника и программиста

371

Глава 48

Железная логика

Логические операции в регистрах

Взгляните на эту, на первый взгляд бессмысленную программу.

var A, B, C : integer;

 

begin

 

 

A:= 5;

B:=16;

C:= A or B;

Writeln( C );

end.

Здесь в переменную C заносится логическая сумма двух других числовых переменных. Но ведь логические операции применяют к булевым данным, причем здесь числа? Так вспомните о регистрах, где эти числа хранятся. Ведь это массивы битов! Содержимое битов можно трактовать и как числа 0 и 1, и как логические значения FALSE и TRUE. Именно так поступает Паскаль, выполняя логические действия с числами. В данном примере логически складываются шестнадцать независимых булевых пар с получением 16 битов результата. Похоже выполняются и другие логические операции с числами.

Известно, что переменная типа BOOLEAN занимает байт целиком, но использует лишь один из восьми битов, — расточительно, не так ли? Тогда как в байте можно хранить 8 булевых значений, в целом числе — 16, а в длинном целом

— 32. Но экономия — не самое главное в жизни. Логические операции с числами дают интересные возможности для шифрования данных, их используют при обработке изображений и в иных случаях.

«Ладно, — скажете, — теперь бы увидеть это наяву». Легко! Наша следующая программа исследует булевы операции с числами. Самая серьезная её часть — функция преобразования байта в строку символов, то есть в двоичное представление этого числа. В программе P_47_1 нечто похожее выполняла функция ConvertFromNumber. Сейчас мы облегчим эту функцию, избавившись от одного параметра — основания системы счисления. К тому же теперь нам надо показать все восемь двоичных разрядов числа, включая незначащие нули. В результате этих изменений появилась на свет функция ConvertTo2, которую мы видим в программе P_48_1.

372

Глава 48

Железная логика

{ P_48_1 – исследование логических операций с числами } function ConvertTo2(aNumber : integer): string;

var n, i : integer;

c : char;

S : string;

begin

 

 

 

S:=''; { Накопитель цифр }

 

 

for i:=1 to 8 do begin

 

 

n:= aNumber mod 2;

 

{ остаток от деления }

c:= Char(n + Ord('0'));

{ преобразуем в цифру }

S:= c + S;

 

{ вставляем цифру слева }

aNumber:= aNumber div 2;

{ частное }

end;

 

 

 

ConvertTo2:= S;

 

 

 

end;

 

 

 

var A, B, C : byte;

{ Операнды и результат }

begin {=== Главная программа ===}

 

repeat

 

 

 

Write('A= '); Readln(A);

 

 

Write('B= '); Readln(B);

 

 

C:= A or B;

{ логическое сложение (объединение) }

Writeln;

 

 

 

Writeln('C= A OR B');

 

 

Writeln('A= ',ConvertTo2(A), A:5);

Writeln('B= ',ConvertTo2(B), B:5);

Writeln('C= ',ConvertTo2(C), C:5);

C:= A and B;

{ логическое умножение (пересечение) }

Writeln;

 

Writeln('C= A AND B');

Writeln('A= ',ConvertTo2(A), A:5);

Writeln('B= ',ConvertTo2(B), B:5);

Writeln('C= ',ConvertTo2(C), C:5);

C:= not A;

{ логическое отрицание (инверсия) }

Writeln;

 

Writeln('C= NOT A');

Writeln('A= ',ConvertTo2(A), A:5);

Writeln('C= ',ConvertTo2(C), C:5); until A=0;

end.

Главная программа не должна вызывать вопросов: после ввода пары чисел и выполнения логических операций с ними, на экран выводятся как исходные числа, так и результаты. Причем выводятся и в двоичной, и в десятичной системах счисления, например:

373

Глава 48

Железная логика

C= A OR B

A= 00001101

13

B= 00001011

11

C= 00001111

15

C= A AND B

A= 00001101

13

B= 00001011

11

C= 00001001

9

C= A XOR B

A= 00001101

13

B= 00001011

11

C= 00000110

6

C= NOT A

A= 00001101

13

C= 11110010

242

По результатам этих опытов выведены правила для логических операций (табл. 12). Логическое отрицание «НЕ» отличается от прочих тем, что применяется к одному операнду.

Табл. 12 – Правила выполнения логических операций с битами

Логическая

 

 

Пример

 

 

Правило

 

 

операция

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

«

»

1010

OR

 

Результат единица, если

ХОТЯ БЫ ОДИН

из

ИЛИ

1100

 

 

 

 

 

 

(сложение)

 

 

 

 

операндов равен единице.

 

 

 

 

1110

 

 

 

 

 

 

 

 

«

»

1010

AND

 

Результат единица, если

ОБА

операнда равны

 

И

1100

 

 

 

 

 

 

 

(умножение)

 

 

 

 

единице.

 

 

 

 

 

1000

 

 

 

 

 

 

 

 

«Исключающее

1010

XOR

 

Результат единица, если операнды

 

ИЛИ»

1100

 

 

 

 

 

 

ОТЛИЧАЮТСЯ

.

 

(сравнение)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0110

 

 

 

 

 

 

 

 

«НЕ»

1010

NOT

 

Результат единица, если операнд

 

 

 

 

 

 

(отрицание)

 

 

 

 

 

 

РАВЕН НУЛЮ.

 

0101

 

 

 

 

 

Заменив в этих правилах единицу на TRUE, а ноль на FALSE, вы получите правила для булевых данных.

374

Соседние файлы в папке delphi