IEEE-представление с плавающей точкой
Microsoft Visual C++ соответствует числовым стандартам IEEE. Существует три внутренних вида действительных чисел. В Visual C++ используются действительное число*4 и действительное число*8. Действительное число*4 объявляется с использованием слова float. Действительное число*8 объявляется с использованием слова double. В 32-разрядном программировании Windows тип данных long double сопоставляется с double. Однако существует поддержка языка ассемблера для вычислений с использованием типа данных действительного числа*10.
Значения хранятся в следующем виде:
Значение |
Хранится как |
---|---|
действительное число*4 |
знаковый разряд, 8-разрядная степень, 23-разрядная мантисса |
действительное число*8 |
знаковый разряд, 11-разрядная степень, 52-разрядная мантисса |
действительное число*10 |
знаковый разряд, 15-разрядная степень, 64-разрядная мантисса |
В форматах действительного числа*4 и действительного числа*8 в начале мантиссы предполагается наличие единицы (1), которая не хранится в памяти, поэтому мантисса на самом деле 24- или 53-разрядная, даже если хранятся только 23 или 52 разряда. В формате действительного числа*10 этот разряд, как правило, хранится.
Степени смещены на половину своего возможного значения. Это означает, что для того, чтобы получить актуальное значение степени, следует вычесть данное смещение из хранимой степени. Если хранимая степень меньше, чем смещение, то это отрицательная степень.
Степени смещены следующим образом:
Степень |
Смещение |
---|---|
8-разрядная (действительное число*4) |
127 |
11-разрядная (действительное число*8) |
1023 |
15-разрядная (действительное число*10) |
16383 |
Данные степени не являются степенями числа 10; это степени числа 2. То есть значение 8-разрядной хранимой степени может доходить до 127. Значение 2**127 примерно равно 10**38, что является реальным ограничением действительного числа*4.
Мантисса хранится в виде двоичной дроби формы 1.ХХХ... . Значение данной дроби больше или равно 1 и меньше или равно 2. Следует учитывать, что действительные числа всегда хранятся в нормализованной форме; то есть мантисса сдвинута влево таким образом, что старший разряд мантиссы всегда равен 1. Поскольку этот разряд всегда равен 1, то он полагается (но не хранится) в формате действительного числа*4 и действительного числа*8. Предполагается, что двоичная (не десятичная) точка расположена непосредственно справа от единицы в начале.
В таком случае для различных размеров используется следующий формат:
Format |
BYTE 1 |
BYTE 2 |
BYTE 3 |
BYTE 4 |
... |
BYTE n |
---|---|---|---|---|---|---|
действительное число*4 |
SXXX XXXX |
XMMM MMMM |
MMMM MMMM |
MMMM MMMM |
|
|
действительное число*8 |
SXXX XXXX |
XXXX MMMM |
MMMM MMMM |
MMMM MMMM |
... |
MMMM MMMM |
действительное число*10 |
SXXX XXXX |
XXXX XXXX |
1MMM MMMM |
MMMM MMMM |
... |
MMMM MMMM |
S представляет знаковый разряд, X являются разрядами степени, а M являются разрядами мантиссы. Следует учесть, что крайний левый разряд полагается в форматах действительного числа*4 и действительного числа*8, но присутствует как "1" в BYTE3 формата действительного числа*10.
Чтобы правильно сдвинуть двоичную точку, следует сначала устранить смещение степени, а затем переместить двоичную точку вправо или влево на соответствующее количество разряд.
Примеры
Далее приведены несколько примеров формата действительного числа*4.
В следующем примере знаковый разряд равен нулю, хранимая степень имеет значение 128, или 1000000 в двоичной форме, что равно 127 плюс 1. Хранимая мантисса имеет значение (1.) 0000000 ... 0000 0000, где в начале есть единица и двоичная точка, поэтому в действительности мантисса имеет значение 1.
SXXX XXXX XMMM MMMM ... MMMM MMMM 2 = 1 * 2**1 = 0100 0000 0000 0000 ... 0000 0000 = 4000 0000
То же самое, что и +2, за исключением того, что задан знаковый разряд. Это верно в отношении всех форматов чисел с плавающей точкой IEEЕ.
-2 = -1 * 2**1 = 1100 0000 0000 0000 ... 0000 0000 = C000 0000
Та же мантисса, степень увеличена на единицу (смещенное значение равно 129 или 10000001 в двоичной форме.
4 = 1 * 2**2 = 0100 0000 1000 0000 ... 0000 0000 = 4080 0000
Та же степень, мантисса больше на половину — она равна (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 = 40C0 0000
Та же степень, как и другие степени числа 2, мантисса на единицу меньше чем двойка при 127, или 01111111 в двоичной форме.
1 = 1 * 2**0 = 0011 1111 1000 0000 ... 0000 0000 = 3F80 0000
Смещенная степень имеет значение 126, 011 1111 0 в двоичной форме, а мантисса имеет значение (1.) 100 0000 ... 0000 0000, что равно 1 1/2.
.75 = 1.5 * 2**-1 = 0011 1111 0100 0000 ... 0000 0000 = 3F40 0000
То же самое, что два, за исключением того, что в мантиссе задан разряд, представляющий 1/4.
2.5 = 1.25 * 2**1 = 0100 0000 0010 0000 ... 0000 0000 = 4020 0000
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 1101 = 3DCC CCCD
0 = 1.0 * 2**-128 = all zeros--a special case.