904 Приложение Б
Модель плавающей запятой
Давайте вкратце рассмотрим модель плавающей запятой. Стандарт представляет значение с плавающей запятой х как степень основания системы счисления, умноженная на дробную часть, которая представлена в этой системе счисления, в отличие от экспоненциальной формы записи языка С, где мы можем записать 876.54 в виде 0.87654ЕЗ. Как и можно было ожидать, формальное представление выглядит более внушительно:
Выражаясь кратко, эта формула представляет число как результат умножения показателя степени, или экспоненты (е), основания системы счисления (b) на значащую часть числа, т.е. многозначную дробную часть.
Ниже описаны различные компоненты формального представления.
• s — знак (±1).
• b — это основание системы счисления. Наиболее распространенным значением является 2, т.к. в процессорах с плавающей запятой обычно применяется двоичная арифметика.
• e представляет целочисленную экспоненту. (Ее не следует путать с числовой константой е, используемой в качестве основания для натуральных логарифмов.) Экспонента будет ограничена диапазоном, имеющим минимальное и максимальное значение. Эти значения будут зависеть от количества битов, выделенных для хранения экспоненты.
• f>k представляет возможные цифры для основания системы счисления б, например, при основании 2 возможными цифрами являются 0 и 1, а при основании 16 — цифры из диапазона от 0 до F.
• р — это точность, т.е. количество цифр по основаниюb, применяемых для представления значащей части числа. Значение р будет ограничено количеством битов, выделенных для хранения значащей части числа.
Понимание этого представления является ключом к пониманию содержимого float.h и fenv.h, поэтому давайте ознакомимся с двумя примерами, иллюстрирующими работу представления плавающей запятой.
Прежде всего, предположим, что основанием системы счисления б является 10, а точность р составляет 5. Тогда значение 24,51 можно было бы записать следующим образом:
(+1)10^(2/10 + 4/100 + 5/1000 + 1/10000 + 0/100000)
Полагая, что компьютер способен хранить десятичные цифры, он мог бы сохранить знак, экспоненту 3, а также пять значений f>k— 2, 4, 5, 1 и 0. (Здесь f>1 — это 2, f>2 - 4 и т.д.) Таким образом, значащей частью является 0.24510. Умножение ее на 10>3 дает 24.51.
Далее предположим, как более распространенную ситуацию, что основание системы счисления b представляет собой 2. Пусть р равно 7, экспонента равна 5, а значащая часть числа хранится как 1011001, используя 7 двоичных цифр, как описано посредством р. Будем считать, что знак числа положителен.
Справочные материалы 905
Тогда согласно формуле мы можем построить число так:
х= (+1 )2>5( 1/2 +0/4 + 1/8 + 1/16 + 0/32 + 0/64 + 1/128)
= 32( 1/2 +0/4 + 1/8 + 1/16 + 0/32 + 0/64 + 1/128)
= 16 + 0 + 4 + 2 +0 + 0 + 1/4 = 22.25
Многие макросы из float.h имеют отношение к этому представлению. Например, для значения типа float макрос FLT_RADIX — это b, т.е. применяемое основание системы счисления, a FLT_MANT_DIG — это р, т.е. количество цифр (по основанию b) в значащей части числа.