Чтение онлайн

на главную - закладки

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

Ошибка исчезнет, если тип переменной

I
изменить на
Integer
— в этом случае верхняя граница цикла получит корректное значение -1, и цикл действительно не выполнится ни разу. Если на панели будет находиться хотя бы один компонент, ошибки тоже не будет, потому что верхняя граница цикла не выйдет из диапазона неотрицательных чисел.

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

Integer
, а если по каким-то причинам приходится использовать переменную типа
Cardinal
, то необходимо внимательно следить за тем, какие значения принимают границы типа.

Примечание

Строго

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

3.2. Неочевидные особенности вещественных чисел

Если рассмотренные в предыдущих разделах особенности целых чисел могли быть неочевидными только начинающим, то вещественные числа могут преподнести сюрпризы даже достаточно опытным программистам, т.к. их поведение существенно дальше от интуитивных представлений, и эти неожиданности не ограничиваются выходом та пределы диапазона. Существующая литература по Delphi, в основном, считает этот вопрос несущественным и обходит его стороной, в результате чего программист, впервые столкнувшийся с одним из таких сюрпризов, впадает в недоумение и испытывает желание "попрыгать вокруг компьютера с бубном". Здесь мы попытаемся восполнить этот пробел и показать, что необъяснимые на первый взгляд явления на самом деле просты и предсказуемы, если известно, как реализуется вещественная арифметика компьютером.

3.2.1. Двоичные дроби

Для начала — немного математики. В школе мы проходим два вида дробей простые и десятичные. Десятичные дроби, по сути дела, представляют собой разложение числа по степеням десяти. Так, запись 13,6704 означает число, равное 1·101 + 3·100 + 6·10– 1 + 7·10– 2 + 0·10– 3 + 4·10– 4. Но внутреннее представление всех чисел в компьютере, в том числе и вещественных, не десятичное, а двоичное. Поэтому он использует двоичные дроби. Они во многом похожи на десятичные, но основанием степени у них служит двойка. Так, двоичная дробь 101.1101 — это 1·22 + 0·21 + 1·20 + 1·2– 1 + 1·2– 2 + 0·2– 3 + 1·2– 4. В десятичном представлении это число равно 5,8125, в чем нетрудно убедиться с помощью любого калькулятора.

Теперь вспомним научный формат записи десятичного числа. Первым в этой записи идет знак числа (плюс или минус). Дальше идет так называемая мантисса (число от 1 до 10). Затем идет экспонента (степень десяти, на которую надо умножить мантиссу, чтобы получить нужное число). Итак, уже упоминавшееся число 13,6704 запишется в этом формате как 1.36704·101 (или 1.36704E1 по принятым в компьютере правилам). Если записываемое число меньше единицы, экспонента будет отрицательной. Аналогичная запись существует и в двоичной системе. Так, 101.1101 запишется в виде 1.011101*1010 (везде использована двоичная форма записи, так что 1010 означает 22). Именно такое представление реализовано в компьютере. Двоичная точка в такой записи не остается на одном месте, а сдвигается на величину, указанную в экспоненте, поэтому такие числа называются числами с плавающей точкой (floating point numbers).

3.2.2. Вещественные типы Delphi

В Delphi существует четыре вещественных типа:

Single
,
Double
,
Extended
и
Real
. Их общий формат одинаков (рис. 3.1, а).

Знак — это всегда один бит. Он равен нулю для положительных чисел и единице для отрицательных. Что же касается размеров мантиссы и экспоненты, то именно в них и заключается различие между типами.

Прежде чем перейти к конкретным цифрам, рассмотрим подробнее тип

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

а) общий вид вещественного числа

б)

Двоичное представление числа типа Single

Рис. 3.1. Хранение вещественного числа в памяти

Микропроцессор Intel 8086/88 и его улучшенные варианты — 80286 и 80386 — также не имели аппаратной поддержки вещественных чисел. Но у систем на базе этих процессоров была возможность подключения так называемого сопроцессора. Эта микросхема работала с памятью через шины основного процессора и обеспечивала аппаратную поддержку вещественных чисел. В системах средней руки гнездо сопроцессора обычно было пустым, т.к. это уменьшало цену (разумеется, вставить туда сопроцессор не было проблемой). Для каждого центрального процессора выпускались свои сопроцессоры, маркировавшиеся Intel 8087, 80287 и 80387 соответственно. Были даже сопроцессоры, выпускаемые другими фирмами. Они работали быстрее, чем сопроцессоры Intel, но появлялись на рынке позже. Тип вещественных чисел, поддерживаемый сопроцессорами, не совпадает с

Real
. Он определяется стандартом IEEE (Institute of Electrical and Electronics Engineers).

Чтобы обеспечить в своих системах поддержку типов IEEE, Borland вводит в Turbo Pascal типы

Single
,
Double
и
Extended
.
Extended
— это основной для сопроцессора тип, a
Single
и
Double
получаются из него очень простым усечением. Система команд сопроцессора допускает работу с этими типами: при загрузке числа типа
Single
или
Double
во внутренний регистр сопроцессора последний конвертирует их в
Extended
. Напротив, при выгрузке чисел этих типов из регистра в память сопроцессор усекает их до нужного размера. Внутренние же операции всегда выполняются с данными типа
Extended
(впрочем, из этого правила есть исключение, на котором мы остановимся позже, после детального рассмотрения формата различных типов).
Single
и
Double
позволяют экономить память. Ни один из них также не совпадает с типом
Real
. В системах с сопроцессорами новые типы обрабатываются заметно (в 2–3 раза) быстрее, чем
Real
(это с учетом того, что тип
Real
после соответствующего преобразования также обрабатывался сопроцессором; если же сравнивать обработку типа
Extended
на машине с сопроцессором и
Real
на машине без сопроцессора, то там на отдельных операциях достигалась разница в скорости примерно в 100 раз). Чтобы программы с этими типами можно было выполнять и в системах без сопроцессора, была предусмотрена возможность подключать к ним программный эмулятор сопроцессора. Обработка этих типов эмулятором была медленнее, чем обработка
Real
.

Начиная с 486-й серии Intel берет курс на интеграцию процессора и сопроцессора в одной микросхеме. Процент брака в микросхемах слишком велик, поэтому Intel идет на хитрость: если у микросхемы брак только в сопроцессорной части, то на этом кристалле прожигаются перемычки, блокирующие сопроцессор, и микросхема продается как процессор 80486SX, не имеющий встроенного сопроцессора (в отличие от полноценной версии, которую назвали 80486DX). Бывали и обратные ситуации, когда сопроцессор повреждений не имел, зато процессор был неработоспособен. Такие микросхемы превращали в "сопроцессор 80487". Но это уже из области экзотики, и, по имеющейся у нас информации, до России такой сопроцессор не дошел.

Процессор Pentium во всех своих вариантах имел встроенный блок вычислений с плавающей точкой (FPU — Floating Point Unit), и отдельный сопроцессор ему не требовался. Таким образом, с приходом этого процессора тип

Real
остался только для обратной совместимости, а на передний план вышли типы
Single
,
Double
и
Extended
. Начиная с Delphi 4, тип
Real
становится синонимом типа
Double
, а старый 6-байтный тип получает название
Real48
.

Здесь и далее под словом

Real
мы будем понимать старый 6-байтный тип.

Примечание

Существует директива компилятора

{$REALCOMPATIBILITY ON/OFF}
, при включении которой (по умолчанию она отключена)
Real
становится синонимом
Real48
, а не
Double
.

Размеры полей для различных вещественных типов указаны в табл. 3.1.

Таблица 3.1. Размеры полей в вещественных типах

Поделиться:
Популярные книги

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»

Фиктивный брак

Завгородняя Анна Александровна
Фантастика:
фэнтези
6.71
рейтинг книги
Фиктивный брак

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Держать удар

Иванов Дмитрий
11. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Держать удар

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Зауряд-врач

Дроздов Анатолий Федорович
1. Зауряд-врач
Фантастика:
альтернативная история
8.64
рейтинг книги
Зауряд-врач

По дороге на Оюту

Лунёва Мария
Фантастика:
космическая фантастика
8.67
рейтинг книги
По дороге на Оюту

Мастер 5

Чащин Валерий
5. Мастер
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Мастер 5

Не лечи мне мозги, МАГ!

Ордина Ирина
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.00
рейтинг книги
Не лечи мне мозги, МАГ!

Измена. Право на семью

Арская Арина
Любовные романы:
современные любовные романы
5.20
рейтинг книги
Измена. Право на семью

Крепость над бездной

Лисина Александра
4. Гибрид
Фантастика:
боевая фантастика
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Крепость над бездной

Неудержимый. Книга XXI

Боярский Андрей
21. Неудержимый
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Неудержимый. Книга XXI