7.1.2. Вещественные типы

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

Таблица 7.4. Вещественные типы

Длина, байт | Название | Количество значащих цифр | Диапазон значений
8 4 8 10 8 8 | Real Single Double Extended Comp Currency | 15…16 7…8 15…16 19…20 19…20 19…20 | 5.0*10e-324…1.7*10e308 1.5*10e-45…3.4*10e38 5.0*10e324…1.7*10e308 3.4*10-4951…1.1*10e4932 -2e63…+2e63-1 +/-922 337 203 685477,5807

Примечание

> В предыдущих версиях Delphi 1...3 тип Real занимал 6 байт и имел диапазон значений от2, 9*10 -39 до 1,7*10 38 . В версиях 4 и 5 этот тип эквивалентен типу Double. Если требуется (в целях совместимости) использовать 6-байтньш Real, нужно указать директиву компилятора {SREALCOMPATIBILITY ON}.

> Как видно из табл. 7.4, вещественное число в Object Pascal занимает от 4 до 10 смежных байт и имеет следующую структуру в памяти ПК:

S | е | M

Здесь s - знаковый разряд числа; е - экспоненциальная часть; содержит двоичный порядок; m - мантисса числа.

Мантисса m имеет длину от 23 (для single) до 63 (для Extended) двоичных разрядов, что и обеспечивает точность 7...8 для single и 19...20 для Extended десятичных цифр. Десятичная точка (запятая) подразумевается перед левым (старшим) разрядом мантиссы, но при действиях с числом ее положение сдвигается влево или вправо в соответствии с двоичным порядком числа, хранящимся в экспоненциальной части, поэтому действия над вещественными числами называют арифметикой с плавающей точкой (запятой).

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

Например, если “машинное эпсилон” (см. пример п. 5.4.3) вычисляется с помощью такой программы:

type

RealType = Real;

var

Epsilon : RealType;

begin

Epsilon := 1;

while l+Eps4.1on/2 > 1 do

Epsilon := Epsilon/2;

IbOutput.Caption := FloatToStr(Epsilon)

end;

то независимо от объявления типа RealType (он может быть single, Real, Double или Extended) на печать будет выдан результат

1.08420217248550Е-0019

что соответствует типу Extended. Происходит это по той причине, что все операнды вещественного выражения 1+Epsilon/2 в операторе while перед вычислением автоматически преобразуются к типу Extended. Чтобы получить правильный результат, программу необходимо изменить следующим образом:

type

RealType = Real;

var

Epsilon, Epsl : RealType;

begin

Epsilon := 1;

repeat

Epsilon := Epsilon/2;

Epsl := 1 + Epsilon

until Epsl = 1;

IbOutput.Caption := FloatToStr(2*Epsilon)

end.

Особое положение в Object Pascal занимают типы comp и Currency, которые трактуются как вещественные числа с дробными частями фиксированной длины: в comp дробная часть имеет длину 0 разрядов, т. е. просто отсутствует, в currency длина дробной части -4 десятичных разряда. Фактически оба типа определяют большое целое число со знаком, сохраняющее 19...20 значащих десятичных цифр (во внутреннем представлении они занимают 8 смежных байт). В то же время в выражениях comp и currency полностью совместимы с любыми другими вещественными типами: над ними определены все вещественные операции, они могут использоваться как аргументы математических функций и т. д. Наиболее подходящей областью применения этих типов являются бухгалтерские расчеты.

Для работы с вещественными данными могут использоваться встроенные математические функции, представленные в табл. 7.5. В этой таблице Real означает любой вещественный тип, integer - любой целый тип.

Таблица 7.5. Стандартные математические функции Object Pascal

Обращение | Тип параметра | Тип результата | Примечание
abs (x) | Real, Integer | Тип аргумента Real | Модуль аргумента
Pi | - | << | П =3.141592653...
ArcTan(x) |  |  | Арктангенс (значение в радианах)
cos (x) | To же << | To же << | Косинус, угол в радианах
exp(x) | << | << | Экспонента
frac(x) | << | << | Дробная часть числа
int(x) | << | << | Целая часть числа
ln(x) | << | << | Логарифм натуральный
Random | - | << | Псевдослучайное число, равномерно распределенное в диапазоне 0...[1]
Random.fx) | Integer | Integer | Псевдослучайное целое число, равномерно распределенное в диапазоне 0...(х-1)
Randomize | - | - | Инициация генератора псевдослучайных чисел
sin (x) | Real | Real | Синус, угол в радианах
sqr(x) | To же | To же | Квадрат аргумента
sqrt(x) | << | << | Корень квадратный

Примечание

> На заметку Генератор псевдо случайных чисел представляет собой функцию которая берет некоторое целое число, называемое базовым, изменяет, его разряды По определенному алгоритму и выдает новое число результат. Одновременно с этим новое число становится базовым.прД следующем обращении к функций; и т. д. (Так как алгоритм процедуры не меняется: в ходе ее работы, числа называются псевдослучайна ми.) В системном модуле System, который автоматически доступен любой программе, базовое число хранится в переменной с именеД RandSeek и всегда имеет начальное значение.О. :Это означает, последовательном обращении к Random в разных, программах (или при нескольких прогонах одной программы) будет всегда вь1лапа'оД на и, та же прследовательность псевдослучайных чисел. НапримёД при; следующём обрабЬтчике bbRunCl.i.ck окно, нашей .учебной программы будет иметь вид, показанный на рис. 7.2:

> procedure TfinExaniple.bbRunCliak(Sender:TObject);

> var

> S,3S: String;.

> begin

> S='';

> for k :=1 to 300 do

> SS := IntToStr (Random (1000))

> while Length(SS)<3 do

> if k mod 2С=0 then

> begin

> S : = '' ;

> end

> end

> end;

> (В программе выводятся 300 псевдослучайных чисел, которые группируются в строки по 20 чисел и дополняются ведущими нулями, если число имеет меньше трех цифр.) Если вы захотите повторить программу, вы получите точно такую же последовательность чисел, что н на рис. 7.2. С помощью процедуры Randomize в переменную RandSeek помещается

> численное значение системного времени, что привёдет к генерации, другой последовательности. Обращение к этой процедуре нужно сделать в самом начале обработчика.

Рис. 7.2. Последовательность псевдослучайных чисел

Начиная с версии 2 в Delphi включен модуль Match, который существенно расширяет перечисленный в табл. 7.5 набор встроенных математических функций. Особенностью реализации содержащихся в нем почти 70 функций и процедур является их оптимизация для работы с арифметическим сопроцессором класса Pentium, так что все они производят необходимые вычисления за рекордно малое время.

Исходный текст содержится в файле файле Source\Rtl\Sys\Match.pas каталога размещения Delphi. В прил. 3 перечисляются подпрограммы модуля Match.