Чтобы обеспечить в своих системах поддержку типов 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.
Тип | Размер типа, байты | Размер мантиссы, биты | Размер экспоненты, биты |
---|---|---|---|
Single | 4 | 23 | 8 |
Double | 8 | 52 | 11 |
Extended | 10 | 64 | 15 |
Real | 6 | 40 | 7 |
Другие параметры вещественных типов, такие как диапазон и точность, можно найти в справке Delphi.
3.2.3. Внутренний формат вещественных чисел
Рассмотрим тип Single
, т. к. он самый короткий и, следовательно, самый простой для понимания. Остальные типы отличаются от него только количественно. В дальнейшем числа в формате Single
мы будем записывать как s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm, где s означает знаковый бит, е — бит экспоненты, m — бит мантиссы. Порядок хранения битов в типе Single показан на рис. 3.1, б (по принятым в процессорах Intel правилам байты в многобайтных значениях переставляются так. что младший байт идет первым, а старший — последним, и вещественных чисел это тоже касается В мантиссе хранится двоичное число. Чтобы получить истинное значение мантиссы, к ней надо мысленно добавить слева единицу с точкой (т. е., например, мантисса 1010000000000000000000 означает двоичную дробь 1.101). Таким образом, имея 23 двоичных разряда, мы записываем числа с точностью до 24-х двоичных разрядов.
Экспонента — по определению всегда целое число. Но способ записи экспоненты в вещественных числах не совпадает с рассмотренным ранее способом записи чисел со знаком. Ноль в этом представлении записывается как 01111111 (в обычном представлении это равно 127). Соответственно. 10000000 (128 в обычном представлении) означает единицу, а 01111110 (126) означает -1, и т. д. (т. е. из обычного беззнакового числа надо вычесть 127, и получится число, закодированное в экспоненте). Такая запись чиста называется