Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Microsoft C++ (MSVC) поддерживает стандартные числовые форматы IEEE. В стандарте IEEE-754 описываются форматы с плавающей запятой, которые используются для аппаратного представления действительных чисел. Есть как минимум пять внутренних числовых форматов для чисел с плавающей запятой, которые могут быть представлены в оборудовании, предназначенном для компилятора MSVC. Компилятор использует только два из них. В MSVC используются форматы с одиночной (4 байта) и двойной (8 байтов) точностью. Объявление одиночной точности выполняется с помощью ключевого слова float. Двойная точность объявляется с помощью ключевого слова double. В стандарте IEEE определяются еще форматы половинной (2 байта) и четырехкратной (16 байтов) точности, а также формат расширенной двойной (10 байтов) точности, который реализуется некоторыми компиляторами C и C++ как тип данных long double. В компиляторе MSVC тип данных long double рассматривается как отдельный тип, но в качестве типа хранения с ним сопоставляется тип double. Тем не менее вычисления с использованием других форматов, в том числе расширенной двойной точности, могут поддерживаться некоторым оборудованием на собственном уровне или на уровне языка ассемблера.
Значения хранятся в следующем виде:
| Значение | Хранится как |
|---|---|
| одинарная точность | бит знака, 8-битная экспонента, 23-битная мантисса |
| двойная точность | разряд знака, 11 разрядов показателя степени, 52 разряда значащей части |
В форматах с одиночной и двойной точностью в дробной части предполагается первый символ 1. Дробная часть называется значащей частью или мантиссой. Это начальное значение 1 не сохраняется в памяти, так что по сути значащая часть имеет длину 24 или 53 бита, из которых хранится на один бит меньше. В формате двойной расширенной точности этот бит действительно сохраняется.
Показатели степени смещены на половину своей возможной величины. Это значит, что для получения фактического значения экспоненты необходимо вычесть это смещение из хранящегося в памяти значения. Если сохраненное в памяти значение экспоненты меньше смещения, значит экспонента отрицательная.
Смещение показателя степени определяется следующим образом:
| Показатель степени | Смещён на |
|---|---|
| 8-разрядный (одинарная точность) | 127 |
| 11 бит (двойная точность) | 1023 |
Эти экспоненты являются степенями двойки, а не десятки. Таким образом, 8-битные показатели степени в диапазоне от –127 до 127 хранятся в памяти соответственно в виде значений в диапазоне от 0 до 254. Значение 2127 примерно равно 1038 и определяет фактический предел для чисел с одиночной точностью.
Значащая часть хранится в виде двоичной дроби в форме 1.XXX... Эта часть имеет значение больше 1 и меньше 2. Действительные числа всегда хранятся в нормализованном представлении. В частности, значение значащей части всегда смещается влево, чтобы ее старший бит имел значение 1. Так как этот разряд всегда равен 1, для форматов одиночной и двойной точности его значение принимается по умолчанию и не хранится в памяти. Двоичная (не десятичная) точка располагается непосредственно справа от начальной 1.
Формат представления с плавающей запятой выглядит следующим образом:
| Формат | байт 1 | байт 2 | байт 3 | байт 4 | ... | байт n |
|---|---|---|---|---|---|---|
| одинарная точность | SXXXXXXX |
XMMMMMMM |
MMMMMMMM |
MMMMMMMM |
||
| двойная точность | SXXXXXXX |
XXXXMMMM |
MMMMMMMM |
MMMMMMMM |
... | MMMMMMMM |
S представляет разряд знака, X — это разряды смещенного показателя степени, а M — это значащие разряды. В форматах одинарной и двойной точности самый левый бит считается предполагаемым.
Чтобы правильно определить смещение двоичной точки, необходимо сначала выделить показатель степени, а затем сместить двоичную точку вправо или влево на соответствующее количество разрядов.
Специальные значения
Форматы с плавающей запятой предусматривают некоторые значения, которые обрабатываются особым образом.
Ноль
Ноль не может быть нормализован, что делает его непредставимым в нормализованной форме для значений одинарной и двойной точности. Специальный битовый шаблон из всех нулей представляет 0. Также возможно представить -0 как ноль с установленным битом знака, однако -0 и 0 всегда сравниваются как равные.
Бесконечность
Значения +∞ и −∞ представляются с экспонентой из одних единиц и значащей частью из одних нулей. Бит знака используется для обозначения положительного и отрицательного.
Субнормальные
Можно представить числа меньшей величины, чем наименьшее число в нормализованном представлении. Такие числа называются субнормальными или денормализованными. Если показатель степени состоит из одних нулей, а значащая часть отлична от нуля, то скрытый старший бит значащей части считается равным нулю, а не единице. Точность субнормальных чисел снижается по мере увеличения количества начальных нулей в значащей части.
NaN (не число)
В формате IEEE с плавающей запятой могут быть представлены значения, не являющиеся действительными числами, например 0/0. Значения такого вида называются NaN (не число). Значение NaN представлено показателем степени, состоящим из одних единиц, и значащей частью, отличной от нуля. Существует два вида NaN: тихие NaN (QNaN) и сигнальные NaN (SNaN). Для несигнальных значений NaN старший разряд значащей части равен единице, и эти значения распространяются через выражения. Они представляют неопределенные значения, например результат деления на бесконечность или умножения бесконечности на нуль. Для сигнальных значений NaN старший разряд значащей части равен нулю. Эти значения используются для недопустимых операций, указывая на аппаратное исключение, связанное с обработкой чисел с плавающей запятой.
Примеры
Ниже приведены примеры в формате одинарной точности:
Для значения 2 знаковый бит имеет значение 0. Сохраняется экспонента 128, то есть двоичное значение 1000 0000, вычисляемое как 127 плюс 1. Хранимый двоичный знак имеет значение (1.) 000 0000 0000 0000 0000, что имеет подразумеваемую ведущую 1 и двоичную точку, поэтому фактический знак является одним.
Значение Формула Двоичное представление Шестнадцатеричное 2 1 * 21 0100 0000 0000 0000 0000 0000 0000 0000 0x40000000 Значение –2. То же, что и + 2, однако в этом случае задан разряд знака. Отрицательные значения всех чисел с плавающей запятой в формате IEEE задаются одинаково.
Значение Формула Двоичное представление Шестнадцатеричное -2 –1 * 21 1100 0000 0000 0000 0000 0000 0000 0000 0xC0000000 Значение 4. Тот же знак, показатель степени увеличивается на единицу (смещенное значение 129 или 100 0000 1 в двоичном формате).
Значение Формула Двоичное представление Шестнадцатеричное 4 1 *2 2 0100 0000 1000 0000 0000 0000 0000 0000 0x40800000 Значение 6. Тот же показатель степени; значащая часть увеличивается наполовину. Это (1.) 100 0000 ... 0000 0000, поскольку, так как это двоичная дробь, составляет 1 1/2, потому что значения дробных цифр — 1/2, 1/4, 1/8 и т. д.
Значение Формула Двоичное представление Шестнадцатеричное 6 1.5 *2 2 0100 0000 1100 0000 0000 0000 0000 0000 0x40C00000 Значение 1. Та же значащая часть, что и для остальных степеней двух; смещенный показатель степени на единицу меньше, чем у двух при 127, то есть 011 1111 1 в двоичном формате.
Значение Формула Двоичное представление Шестнадцатеричное 1 1 * 20 0011 1111 1000 0000 0000 0000 0000 0000 0x3F800000 Значение 0,75. Смещенный экспонент равен 126, 011 1111 0 в двоичном формате, а мантисса — (1.) 100 0000 ... 0000 0000, что составляет 1 1/2.
Значение Формула Двоичное представление Шестнадцатеричное 0.75 1.5 * 2-1 0011 1111 0100 0000 0000 0000 0000 0000 0x3F400000 Значение 2,5. Почти идентично два, за исключением того, что в значащей части установлен бит, представляющий 1/4.
Значение Формула Двоичное представление Шестнадцатеричное 2,5 1.25 * 21 0100 0000 0010 0000 0000 0000 0000 0000 0x40200000 1/10 — это повторяющаяся часть в двоичном формате. Значащая часть здесь немного меньше 1,6, а экспонента с учетом смещения указывает, что 1,6 нужно разделить на 16. (Это 011 1101 1 в двоичном файле, что составляет 123 в десятичном разряде.) Истинный экспонент равен 123 – 127 = -4, что означает, что коэффициент умножения равен 2-4 = 1/16. Хранимая в памяти значащая часть округляется до последнего разряда, чтобы представить выходящие за пределы числа с максимально возможной точностью. (Величины 1/10 и 1/100 нельзя точно представить в двоичном формате по той же причине, по которой 1/3 нельзя представить в десятичном.)
Значение Формула Двоичное представление Шестнадцатеричное 0,1 1.6 * 2-4 0011 1101 1100 1100 1100 1100 1100 1101 0x3DCCCCCD Нуль рассматривается как особый случай. Он использует формулу для минимального возможного представимого положительного значения, при котором все биты равны нулю.
Значение Формула Двоичное представление Шестнадцатеричное 0 1 * 2-128 0000 0000 0000 0000 0000 0000 0000 0000 0x00000000