Числа с плавающей запятой
Числа с плавающей запятой, или вещественные числа, широко используются в повседневной практике. Однако в компьютерных программах их долгое время старались не применять. И сегодня, в критичных по времени выполнения частях программ, вместо чисел с плавающей запятой применяют целые числа. Причина в том, что операции с плавающей точкой выполняются гораздо медленне, чем операции с байтами и словами. Другой причиной является то, что числа с плавающей точкой обеспечивают лишь приближенное представление. Это сказывается, например, на финансовых программах. Несмотря на высокую точность представления чисел с плавающей запятой в современных процессорах, длинная цепочка вычислений может прививести к погрешности не только в последнем разряде, но и в тысячных, и даже в десятых долях. Особенно если оперировать большими числами.
Как видно, число с плавающей запятой (или точкой), состоит из мантиссы и порядка. Рассмотрим число 24324,43534. Его можно представить, в так называемой научной нотации, как 2,432443534·104. Здесь мантисса 2,432443534, а порядок 4. В общем виде число с плавающей запятой можно представить так:
[+|-]d0,d1d2d3...dn·10[+|-]dp
Здесь [+|-] обозначает необязательный знак числа или порядка. di это десятичная цифра (от 0 до 9), причем d0 обязательно должна быть не равна 0, естественно, если само число не 0. dp это десятичный порядок, который тоже состоит из цифр от 0 до 9. Для двоичных чисел общий вид будет таким же, за маленьким исключением:
[+|-]b0,b1b2b3...bn·2[+|-]bp
Здесь bi это двоичная цифра (0 или 1), причем b0 обязательно должна быть 1. bp это двоичный порядок, состоящий из двоичных цифр. Обратите внимание, что для двоичного числа с плавающей запятой порядок это степень двойки, а не 10.
Я буду рассматривать формат чисел с плавающей запятой только применительно к процессорам Intel 80х86. А вот операции с этими числами описываются обычными математическими правилами и не зависят от типа процессора. Итак, в процессорах Intel, числа с плавающей запятой могут хранится в трех форматах: одинарной точности, двойной точности и расширенной точности. Основное отличие этих форматов заключается в количестве бит, отводимых под мантиссу и порядок. Для чисел одинарной точности мантисса занимает 24 бита, а порядок 8. Для двойной точности, мантисса 53 бита, порядок 11 бит. Для расширенной точности, мантисса 64 бита, порядок 15 бит. Знаковый бит как всегда определяет знак числа, однако мантисса хранится не в дополнительном, а в прямом коде. Следовательно возможно появление двух нулей, положительного и отрицательно, +0 и -0. Порядок не только не выровнен на гранцу байта, но и хранится в экзотическом, смещенном, виде:
хранимый порядок = истинный порядок + смещение
Значение смещения для соответствующих форматов, в десятичном эквиваленте, равно +127, +1023, +16383, или в двоичном виде 1111111, 1111111111, 11111111111111. Приведу примеры, для облегчения понимания, в десятичном виде и для чисел одинарной точности. Порядок -6 будет храниться как 121, а +17 как 144.
Мантисса тоже хранится достаточно хитро. Для начала посчитаем: один бит знаковый, 8 бит порядок, 24 бита мантисса, итого 33 бита! Как же так, ведь двойное слово занимает только 32 бита? Вспомним общий вид двоичного числа с плавающей запятой, точнее то, что b0 обязательно должна равняться 1. Раз одна из цифр числа всегда известна, то зачем ее хранить? Вот и получается, что хранятся только 23 бита из 24, 52 из 53. Для чисел расширеной точности сделано исключение - хранятся все цифры числа, даже b0. Говоря другими словами, в форматах одинарной и двойной точности мантисса хранится со скрытым битом. Теперь о десятичной, извиняюсь, двоичной точке. Эта точка не хранится! Мантисса хранится как целое число. Например мантисса 1.10101010111110011101001 в результате всех преобразований будет храниться как 10101010111110011101001.
Почему же для расширенного формата сделано исключение? Во первых, это нестандартный формат, он присутствует только в процессорах Intel. Во вторых, числа внутри процессора хранятся и обрабатываются именно в этом формате. При загрузке числа из памяти, или при сохранении в память, выполняются необходимые преобразования. Собственно все дело именно в использовании этого формата для выполнения операций внутри процессора. Хранение мантиссы со скрытым битом не позволяет представлять не нормализованные числа, а результат операции может оказаться как раз не нормализованым. Расширеный формат позволяет представлять такие числа благодаря хранению всех разрядов.
Понятие нормализованного числа известно из математики. Приведенные выше общие виды десятичных и двоичных чисел описывают именно нормализованные числа. Однако результат оперции над двумя нормализованными числами может оказаться не нормализованным. В этом случае процессор выполняет процедуру нормализации, которая сводится к сдвигу двоичной точки в соответсвующую позицию и корректировке порядка. Например сдиг двоичной точки на один разряд влево вызывает увеличение порядка на 1.
Операции над числами с плавающей точкой. В компьютерах с процессорами Intel 80х86, операции над числами с плавающей запятой выполняет так называемый сопроцессор 80х87. Этот сопроцессор имеет команды для арифметических операций, тригонометрических операций, извлечения корня, преобразований форматов чисел, служебные команды. Все операции выполняются по стандартным математическим правилам, поэтому я рассмотрю только четыре арифметических действия, причем в их десятичном эквиваленте.
· СЛОЖЕНИЕ и ВЫЧИТАНИЕ. Вы можете сложить или вычесть два любых числа. Процессор сам выполнит приведение порядков. Например 1,34·104 + 1,2·102 = 1,34·104 + 0,012·104 = 1,352·104.
· УМНОЖЕНИЕ и ДЕЛЕНИЕ. Выполняются по широко известным правилам: при умножении, мантиссы перемножаются, а порядки складываются, при делении, мантиссы делятся, а порядки вычитаются. Например: 1,34·104 · 1,2·102 = 1,608·106
Теперь Вы знаете, практически, все о машинных форматах данных. Практически, потому, что есть еще специализированные процессоры, оперирующие комплексными числами, сигнальные процессоры для обработки аналоговых сигналов и построения цифровых фильтров. У них свои форматы данных. Существуют еще упакованные и зонные форматы. Их используют для вычислений высокой и сверхвысокой точности. Этих форматов я коснусь чуть дальше. В любом случае, для Вас сейчас не должно составить труда разобраться с любым, самым экзотическим форматом.