Вещественные типы
В отличие от порядковых типов, значения которых всегда сопоставляются с рядом целых чисел и, следовательно, представляются в ПК абсолютно точно, значения вещественных типов определяют произвольное число лишь с некоторой конечной точностью, зависящей от внутреннего формата вещественного числа.
Таблица 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*1038 . В версиях 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, а три других вещественных типа в этом случае получаются простым усечением результатов до нужных размеров и применяются в основном для экономии памяти.
Например, если "машинное эпсилон" (см. пример в этом пункте) вычисляется с помощью такой программы:
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.
1 2 3
8 8 8
| |