5.2. Стандартные скалярные типы данных
5.2.1. Целочисленные типы
В языке Delphi существует девять целочисленных типов:
shortint (короткое целое);
smallint (малое целое);
integer (целое);
longint (длинное целое);
int64 (целое длиной 8 байт);
byte (байт);
word (слово);
longword (длинное слово);
cardinal (основной).
Из них пять типов относится к фундаментальным типам. Два типа относится к обобщенным типам.
Характеристики целочисленных типов иллюстрирует таблица 5.1.
Таблица 5.1 – Характеристики целочисленных типов
Тип |
Диапазон |
Формат |
Классификация |
|
shortint |
-27 ÷ 27 – 1 (-128 ÷ 127) |
1 байт (8 битов со знаком) |
знаковые |
фундамен- тальные |
smallint |
-215 ÷ 215 – 1 (-32768 ÷ 32767) |
2 байта (16 битов со знаком) |
||
longint |
-231 ÷ 231 – 1 (-2147483648 ÷ 2147483647) |
4 байта (32 бита со знаком) |
||
int64 |
-263 ÷ 263 – 1 |
8 байтов (64 бита со знаком) |
||
byte |
0 ÷ 28 - 1 (0 ÷ 255) |
1 байт (8 битов без знака) |
беззнаковые |
|
word |
0 ÷ 216 – 1 (0 ÷ 65535) |
2 байта (16 битов без знака) |
||
longword |
0 ÷ 232 – 1 (0.. 4294967295) |
4 байта (32 бита без знака) |
||
integer |
-215 ÷ 215 – 1 (-32768 ÷ 32767) |
2 байта (16 битов со знаком) * |
знаковый |
обобщен-ные |
cardinal |
0 ÷ 232 – 1 (0.. 4294967295) |
4 байта (32 бита без знака) * |
беззнаковый |
|
Примечание. * - количество байт памяти, требуемых для хранения переменных обобщенных типов данных, приведено для 32-разрядных процессоров семейства x86.
В памяти машины целые числа хранятся в виде двоичного числа с фиксированной точкой (ФТ) и занимают (как видно из таблицы) 1 байт, 2 байта, 4 байта или 8 байтов.
При программировании алгоритмов предпочтение следует отдавать обобщенным типам даных, поскольку они позволяют достичь максимальной скорости выполнения программ на различных моделях микропроцессоров. Переменные обобщенных типов данных могут храниться в памяти по-разному в зависимости от конкретной модели компьютера. Для работы с ними компилятор может генерировать оптимальный код. Однако при использовании переменных обобщенных типов данных нельзя полагаться на формат их хранения в памяти.
Внутреннее представление целых чисел
Рассмотрим внутреннее представление целых чисел в персональных компьютерах на базе, например, 16-разрядных микропроцессоров Intel. Разрядная сетка таких компьютеров может быть представлена так, как показывает рисунок 5.2.
На данном рисунке под каждым разрядом указан его номер (принято нумеровать разряды со стороны младших разрядов, начиная с нуля), а над каждым разрядом – его вес.
Рисунок 5.2 – Разрядная сетка 16-разрядного микропроцессора
Минимальное двоичное число, которое может быть записано в данной разрядной сетке –
(в качестве нижнего индекса указано основание системы счисления).
Максимальное число, которое может быть записано в шестнадцати разрядах –
Этот диапазон (0 ÷ 65535) соответствует формату Word Delphi.
Для типа Byte используется один байт без знака (рисунок 5.3).
В данном случае диапазон представления чисел –
Рисунок 5.3 – Представление типа Byte
Для чисел со знаком старший бит соответствующего поля памяти, отведенного для хранения числа, считается знаковым (рисунок 5.4). Если в нем 0 – число положительное (знак +), 1 – отрицательное (знак –).
Рисунок 5.4 – Представление шестнадцатиразрядных чисел со знаком
Максимальное число (положительное), которое может быть записано в данной разрядной сетке:
Минимальное положительное число:
Отрицательные числа в памяти компьютера хранятся в дополнительном коде.
Дополнительный код (ДК) числа i образуется путем инвертирования (замены значения на противоположное) всех значащих разрядов прямого кода числа и прибавления 1 к самому младшему разряду. Аналогично производится преобразование из дополнительного кода в прямой код.
Например, пусть i = -1.
Дополнительный код числа i может также быть определен по формуле
где n – разрядность представления операндов (включая знак), | i |- модуль i.
Пример 5.1.
Представление чисел для n = 3 (рисунок 5.5).
Рисунок 5.5 – Представление чисел для n = 3
Таблица 5.2 поясняет правила получения дополнительного кода числа из его прямого кода в полученном диапазоне. Здесь: 10СС – десятичная система счисления, 2СС – двоичная система счисления.
Диапазон представления при n = 3:
Исходное число i в 10СС |
Представление числа i в 2СС |
Правило получения ДК 2n – |i| = 8 - |i| |
Примечания |
–4 –3 –2 –1 |
100 101 110 111 |
8 – 4 = 4 8 – 3 = 5 8 – 2 = 6 8 – 1 = 7 |
Формирование дополнительного кода для отрицательных чисел. В знаковом разряде получена единица. |
0 1 2 3 |
000 001 010 011 |
— — — — |
Сохранение прямого кода для положительных чисел. В знаковом разряде – ноль. |
из прямого кода числа при n = 3
Пример 5.2.
Представление целых чисел для n = 16.
Формула для определения дополнительного кода числа в этом случае имеет вид:
Представление целых чисел в формате два байта со знаком иллюстрирует таблица 5.3. Здесь 16СС – шестнадцатеричная система счисления.
Таблица 5.3 – Представление целых чисел в формате два байта со знаком
Исходное число i в 10СС |
Представление числа i в 2СС |
Представление числа i в 16СС |
Примечание |
–215 –215+1 –215+2 -------- -1 |
1000 0000 0000 0000 1000 0000 0000 0001 1000 0000 0000 0010 -------------------------- 1111 1111 1111 1111 |
8000 8001 8002 ----- FFFF |
Формирование дополнительного кода для отрицательных чисел. В знаковом разряде получена единица. |
0 +1 +2 -------- +215 –1 |
0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0010 -------------------------- 0111 1111 1111 1111 |
0000 0001 0002 ----- 7FFF |
Сохранение прямого кода для положительных чисел. В знаковом разряде – ноль. |
Итак, диапазон представления чисел со знаком в шестнадцати разрядах равен
что соответствует типу Smallint в Delphi.
Аналогично представление информации для типа Shortint (рисунок 5.6).
Рисунок 5.6 – Представление восьмиразрядных чисел со знаком
Диапазон представления чисел со знаком в восьми разрядах равен:
Для типа Longint представление информации иллюстрирует рисунок 5.7.
Рисунок 5.7 – Представление тридцатидвухразрядных чисел со знаком
Из данного рисунка следует, что диапазон представления чисел со знаком в тридцати двух разрядах равен:
Целочисленные константы и переменные
В программах целые числа обычно используются в качестве счетчиков (для управления количеством повторений цикла) и в качестве индексов. При обработке целых чисел используется арифметика с ФТ, округления не производятся, вычисления выполняются точно.
Множество целочисленных значений является перенумерованным, порядковым номером каждого значения целочисленного типа является само это значение.
Например, порядковый номер числа 5 равен 5, числа (-5) – (-5), порядковый номер нуля равен нулю.
Переменные целочисленных типов объявляются в разделе описания переменных программы с помощью указания идентификатора типа. Например,
Var
a, b: integer;
c: shortint;
d: word;
Целые константы делятся на два типа – десятичные и шестнадцатеричные:
Признак шестнадцатеричной константы – знак $ перед числом.
Примеры записи десятичных констант:
+16 25 –48
Примеры записи шестнадцатеричных констант:
$F $9A0
Целой константе присваивается целочисленный тип с наименьшим диапазоном, включающим значение этой константы.
Операции над целочисленными данными
Над целочисленными данными в Delphi определены операции, которые представляет таблица 5.4.
В двухместных арифметических и логических операциях (кроме операции деления /) тип результата будет таким же, как общий тип обоих операндов. Перед выполнением операции оба операнда преобразуются к их общему типу. Общим типом является целочисленный тип с наименьшим диапазоном, включающим все возможные значения обоих типов.
Например, общим типом для малого целого (Smallint) и длинного целого (Longint) является Longint. Общим типом для типов Smallint и Word является Longint.
Действие выполняется в соответствии с точностью общего типа.
Для всех целочисленных типов переполнение при выполнении арифметических операций не обнаруживается.
Таблица 5.4 – Операции над целочисленными данными
Группа операций |
Операция |
Вид |
Описание |
Тип результата |
Арифметические операции |
+ – + – * / div
mod |
Одноместная Одноместная Двухместная Двухместная Двухместная Двухместная Двухместная
Двухместная |
Сохранение знака Отрицание знака Сложение Вычитание Умножение Деление Целочисленное деление Остаток целочисленного деления |
Целый Целый Целый Целый Целый Вещественный Целый
Целый |
Логические (побитовые) операции |
not
and
or
xor |
Одноместная
Двухместная
Двухместная
Двухместная |
Поразрядное дополнение целого Поразрядное логическое умножение (И) Поразрядное логическое сложение (ИЛИ) Поразрядное логическое исключающее ИЛИ |
Целый |
Операции сдвига |
shl
shr |
Двухместная
Двухместная |
i shl j – сдвиг влево значения i на j битов i shr j – сдвиг вправо значения i на j битов |
Тип i
Тип i |
Операции сравнения |
= <> < > <= >= |
Двухместная Двухместная Двухместная Двухместная Двухместная Двухместная |
Равно Не равно Меньше Больше Меньше или равно Больше или равно |
Логический |
Примеры и пояснения к выполнению операций над целочисленными данными
Пример 5.3.
Выполнение операций div, mod.
Результат операции А div В равен целой части результата деления А на В. Знак результата определяется по общим правилам деления.
Результат операции А mod В определяется в соответствии с выражением:
Например,
10 div 3 = 3 10 div (-3) = -3
10 mod 3 = 1 10 mod (-3) = 1
(-10) div 3 = -3 (-10) div (-3) = 3
(-10) mod 3 = -1 (-10) mod (-3) = -1
Из данных примеров видно, что знак остатка целочисленного деления соответствует знаку делимого.
Пример 5.4.
Выполнение операций сдвига shl, shr.
Логические операции и операции сдвига осуществляют поразрядную обработку внутренних представлений целочисленных значений. Для правильного использования этих операций необходимо знать внутреннее представление целых чисел в компьютере.
Пусть числа имеют тип Byte.
А) 2 shl 5
Внутреннее представление числа 2:
Сдвиг двоичного представления числа 2 влево на 5 двоичных разрядов дает результат:
Поэтому 2 shl 5 = 64.
Следует обратить внимание, что сдвиг двоичного представления числа влево на один двоичный разряд эквивалентен умножению данного числа на 2. Для предыдущего примера числа на сдвиг двоичного представления числа влево на 5 двоичных разрядов эквивалентен умножению данного числа на 25.
В) 6 shr 2
Внутреннее представление числа 6:
Сдвиг двоичного представления числа 6 вправо на 2 двоичных разряда дает результат:
Поэтому 6 shr 2 = 1.
Сдвиг двоичного представления числа вправо на один двоичный разряд эквивалентен делению данного числа на 2. Для предыдущего примера сдвиг двоичного представления числа вправо на 2 двоичных разряда эквивалентен целой части результата деления данного числа на 22:
Следует обратить внимание, что при сдвиге вправо отрицательных чисел слева вдвигаются нули, что соответствует логическому сдвигу, а не арифметическому.
Пример 5.5.
Выполнение поразрядных логических операций and, or, xor, not.
Выполнение логических операций над соответствующими двоичными разрядами операндов поясняет таблица 5.5.
Таблица 5.5 – Правила выполнения логических операций
And (И, ·) |
Or (Или, +) |
Xor
( |
Not (Не) |
0 · 0 = 0 0 · 1 = 0 1 · 0 = 0 1 · 1 = 1 |
0 + 0 = 0 0 + 1 = 1 1 + 0 = 1 1 + 1 = 1 |
0 0 = 0 0 1 = 1 1 0 = 1 1 1 = 0 |
0→1 1→0 |
Пусть числа имеют тип Byte.
А) 12 and 5
Внутреннее представление числа 12:
Внутреннее представление числа 5:
Результат операции равен
Поэтому 12 and 5 = 4.
В) 12 or 5
Результат операции равен
Поэтому 12 or 5 = 13.
С) 12 xor 5
Результат операции равен
Поэтому 12 xor 5 = 9.
D) not 12
Результат операции равен
Поэтому not 12 = 243.
Встроенные процедуры и функции, определенные над целочисленными данными
Помимо операций над данными целочисленных типов определен ряд встроенных подпрограмм (функций и процедур).
Встроенные процедуры и функции – это процедуры и функции, которые определены в компиляторе языка программирования. Имена встроенных процедур и функций являются предопределенными идентификаторами.
Для получения значения встроенной процедуры или функции в программе записывается ее имя и аргументы в формате, который представляет рисунок 5.8.
Рисунок 5.8 – Синтаксическая диаграмма обращения к подпрограмме
В компиляторе Delphi определено несколько десятков (около 160 в модуле System) встроенных процедур и функций.
Над целочисленными данными определены процедуры и функции, основные из которых содержит таблица 5.6.
Таблица 5.6 – Процедуры и функции, определенные над целочисленными данными
Подпрограмма |
Вид |
Описание |
Тип результата |
Chr(x) |
Функция |
Возвращает символ кодовой таблицы с заданным номером |
char |
Ord(x) |
Функция |
Возвращает порядковый номер скалярного аргумента x (Ord(5) = 5; Ord(0) = 0; Ord(-5) = -5) |
Тип х |
Abs(x) |
Функция |
Абсолютное значение х |
Тип x |
Sqr(x) |
Функция |
|
Тип x |
Dec(x [, n])* |
Процедура |
Уменьшает значение x на величину n (по умолчанию на единицу) |
Тип x |
Inc(x [, n])* |
Процедура |
Увеличивает значение x на величину n (по умолчанию на единицу) |
Тип x |
Odd(x) |
Функция |
Возвращает True (истину), если аргумент нечетный |
логический |
Pred(x) |
Функция |
Возвращает предшествующий элемент в типе аргумента (для целочисленных данных возвращает x - 1) |
Тип x |
Succ(x) |
Функция |
Возвращает следующий элемент в типе аргумента (для целочисленных данных возвращает x + 1) |
Тип x |
Hi(x) |
Функция |
Возвращает второй байт своего аргумента (x:любой целочисленный, если byte или shortint, то вернет 0) |
Byte |
Lo(x) |
Функция |
Возвращает младший байт своего аргумента (x:любой целочисленный) |
Byte |
Swap(x) |
Функция |
Возвращает значение, образованное переменой местами младшего и второго байта своего аргумента (x:целочисленный) |
Тип x |
Random(N) |
Функция |
Возвращает случайное число из диапазона 0..N – 1 (N: longint, результат правильный, если число положительное) |
Тип N |
Sizeof(x) |
Функция |
Возвращает число байт, которые занимает аргумент в памяти (аргумент может быть именем переменной или именем типа). |
целочисленный |
Примечание. * - в квадратные скобки заключена необязательная часть конструкции.
Для получения максимального и минимального значений целочисленного и логического типа заданной переменной могут использоваться соответственно встроенные функции High(x) и Low(x). Например,
High(longword) возвращает значение 4294967295;
Low(smallint) возвращает значение -32768.
Если подпрограмма представляет собой процедуру, то обращение к ней осуществляется с помощью оператора вызова процедуры. Например, Inc(x) –процедура, поэтому обращение к ней имеет вид:
Inc(x);
В результате обращения к данной процедуре значение ее аргумента Х увеличится на единицу.
Если подпрограмма представляет собой функцию, то обращение к ней возможно из тех мест программы, где по синтаксису допускается использование выражений (например, в правой части оператора присваивания). Например, Abs(x) – функция, поэтому обращение к ней имеет вид:
Y = Sqr(x);
В результате обращения к данной функции в Y занесется значение, равное абсолютному значению х.
