А. Григорьев - О чём не пишут в книгах по Delphi
- Название:О чём не пишут в книгах по Delphi
- Автор:
- Жанр:
- Издательство:БХВ-Петербург
- Год:2008
- Город:СПб
- ISBN:978-5-9775-019003
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
А. Григорьев - О чём не пишут в книгах по Delphi краткое содержание
Рассмотрены малоосвещённые вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные механизмы их работы, особенности для протоколов TCP и UDP и др. Большое внимание уделено разбору ситуаций возникновения ошибок и получения неверных результатов в "простом и правильном" коде. Отдельно рассмотрены особенности работы с целыми, вещественными и строковыми типами данных, а также приведены примеры неверных результатов, связанных с ошибками компилятора, VCL и др. Для каждой из таких ситуаций предложены методы решения проблемы. Подробно рассмотрен синтаксический анализ в Delphi на примере арифметических выражений. Многочисленные примеры составлены с учётом различных версий: от Delphi 3 до Delphi 2007. Прилагаемый компакт-диск содержит примеры из книги.
Для программистов
О чём не пишут в книгах по Delphi - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Начиная с 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.Размеры полей в вещественных типах
Тип | Размер типа, байты | Размер мантиссы, биты | Размер экспоненты, биты |
---|---|---|---|
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, и получится число, закодированное в экспоненте). Такая запись чиста называется нормализованной .
Из описанных правил есть исключения. Так, если все биты экспоненты равны нулю (т.е. там стоит число -127), то к мантиссе перед ее началом надо добавлять не "1.", а "0." (денормализованная запись) . Это позволяет увеличить диапазон вещественных чисел. Если бы этого исключения не было, то минимально возможное положительное число типа Single
было бы равно примерно 5,9·10 -39. А так появляется возможность использовать числа до 1,4·10 -45. Побочным эффектом этого является то, что числа, меньшие чем 1,17·10 -38, представляются с меньшей, чем 24 двоичных разряда, точностью. Если все биты в экспоненте равны единице, а в мантиссе — нулю, то мы получаем комбинацию, известную как INF
(от англ. Infinity — бесконечность). Эта комбинация используется тогда, когда результат вычислений превышает максимально допустимое форматом число. В зависимости от значения бита s бесконечность может быть положительной или отрицательной. Если же при такой экспоненте в мантиссе хоть один бит не равен нулю, такая комбинация называется NAN
(Not A Number — не число). Попытки работы с комбинациями NAN
или INF
приводят к ошибке времени выполнения.
Для задания нуля все биты мантиссы и экспоненты должны быть равны нулю (формально это означает 0·10 -127). С учетом описанных правил, если хотя бы один бит экспоненты не будет равен нулю (т.е. экспонента будет больше -127), запись будет считаться нормализованной, и нулевая мантисса будет рассматриваться как единица. Поэтому никакие другие комбинации значений мантиссы и экспоненты не могут дать ноль.
Тип Double
устроен точно так же, разница только в количестве разрядов и в том, какое значение экспоненты берется за ноль. Итак, мы имеем 11 разрядов для экспоненты. За ноль берется значение 1023.
Несколько иначе устроен Extended
. Кроме количественных отличий добавляется еще и одно качественное: в мантиссе явно указывается первый разряд. Это означает, что мантисса 1010… интерпретируется как 1.01, а не как 1.101, как это было в типах Single
и Float
. Поэтому если 23-битная мантисса типа Single
обеспечивает 24-знаковую точность, а 52-битная мантисса Double
— 53-битную, то 64-битная мантисса Extended
обеспечивает 64-х, а не 65-битную точность. Соответственно, при денормализованной форме записи первый разряд мантиссы явно содержит 0. За ноль экспоненты принимается значение 16 383.
Тип Real
, как уже упоминалось, стоит особняком. Во-первых, в нем биты следуют в другом порядке, а во-вторых, нет денормализованной формы. Мы не будем касаться внутреннего устройства типа Real
, т.к. эта информация уже перестала быть актуальной.
3.2.4. "Неполноценный" Extended
Ранее мы отметили, что FPU всегда выполняет все операции в формате Extended
, оговорившись при этом, что есть исключение из этого правила. Здесь мы рассмотрим это исключение.
У FPU существует специальный двухбайтный регистр, называемый управляющим словом . Установка отдельных битов этого регистра диктует то или иное поведение при выполнении операций. Прежде всего, это связано с тем, какие исключения может возбуждать FPU. Другие биты этого регистра отвечают за то, как будут округляться числа, как FPU понимает бесконечность, — всё это можно при необходимости узнать из документации Intel. Нас же будут интересовать только два бита из этого слова: восьмой и девятый. Именно они определяют, как будут обрабатываться числа внутри сопроцессора.
Читать дальшеИнтервал:
Закладка: