Форматы float32 и double64 на пальцах
Вкратце, идея довольна простая: исходное число необходимо привести к нормализованному виду <nobr>1.NNN<sub>2</sub></nobr>
в двоичной системе счисления с помощью битового сдвига, затем записать дробную часть этого числа в мантиссу, а количество сдвигов в экспоненту. И завершающим штрихом сохранить знак исходного числа.
Формат float32 имеет такой вид: <span class="text-red">1s</span><span class="text-green">8e</span><span class="text-blue">23m</span>
, где s — количество бит под знак, e — экспонента, m — мантисса. Для формата double64 вид такой — <span class="text-red">1s</span><span class="text-green">11e</span><span class="text-blue">52m</span>
.
Первый бит кодирует знак числа. Если это ноль, число положительно, в противном случае число отрицательное.
Затем идут восемь бит экспоненты. Если совсем простыми словами, то экспонента — это количество сдвигов запятой в исходном числе, представленном в двоичном виде, для получения нормализованного числа вида <nobr>1.NNN<sub>2</sub></nobr>
. Чтобы получить количество сдвигов из этих восьми бит надо отнять <nobr>127<sub>10</sub></nobr>
. Отрицательная экспонента — сдвиг влево, положительная — сдвиг вправо.
После экспоненты следуют 23
бита мантиссы. Это дробная часть числа <nobr>1.NNN<sub>2</sub></nobr>
.
А теперь практическая часть!
Перевод десятичной дроби во float32
Попробуем с полученными знаниями закодировать число <nobr>-2.625<sub>10</sub></nobr>
.
В двоичном виде это число имеет вид <nobr>10.101<sub>2</sub></nobr>
. Для получения нормализованного числа необходимо запятую сдвинуть влево на один разряд. Получим число <nobr>1.0101<sub>2</sub></nobr>
и экспоненту равной 1
.
Для сохранения экспоненты к ней надо прибавить <nobr>127<sub>10</sub></nobr>
. Получится <nobr><span class="text-green">126</span><sub>10</sub></nobr>
или <nobr><span class="text-green">01111110</span><sub>2</sub></nobr>
в двоичном виде.
Берем нормализованное число <nobr>1.<b>0101</b><sub>2</sub></nobr>
и выделяем мантиссу <nobr><b>0101</b><sub>2</sub></nobr>
. Для сохранения этого числа, которое занимает 4 бита, надо добавить нули справа до 23 бит. Получится число <nobr><span class="text-blue"><b>0101</b>0000000000000000000</span><sub>2</sub></nobr>
.
Знак числа отрицательный, значит первый бит равен единице.
Итог: s=<nobr><span class="text-red">1</span><sub>2</sub></nobr>
e=<nobr><span class="text-green">01111110</span><sub>2</sub></nobr>
m=<nobr><span class="text-blue">01010000000000000000000</span><sub>2</sub></nobr>
, с чем я вас и поздравляю.
Обратный перевод: из float32 в число
Разберем пример из википедии. Есть число во float32 <nobr>0xC0000000<sub>16</sub></nobr>
. В двоичной системе это будет <span class="text-red">1</span><span class="text-green">10000000</span><span class="text-blue">00000000000000000000000</span><sub>2</sub>
.
Разобъем его на компоненты: s=<nobr><span class="text-red">1</span><sub>2</sub></nobr>
e=<nobr><span class="text-green">10000000</span><sub>2</sub></nobr>
m=<nobr><span class="text-blue">00000000000000000000000</span><sub>2</sub></nobr>
.
Мантисса равна нулю, но, как уже было сказано выше, сохраняется только дробная часть мантиссы, а единица отбрасывается. Значит мантисса равна <nobr>1.<span class="text-blue">00000000000000000000000</span><sub>2</sub></nobr>
.
Экспонента равна <nobr><span class="text-green">10000000</span><sub>2</sub></nobr>
или <nobr><span class="text-green">128</span><sub>10</sub></nobr>
, отнимаем <nobr>127<sub>10</sub></nobr>
и получается, что экспонента равна единице.
Возьмем мантиссу и сдвинем точку вправо на эту единицу, получится <nobr>10.0000000000000000000000<sub>2</sub></nobr>
, это <nobr>2<sub>10</sub></nobr>
в десятичной системе счисления.
Знак числа равен единице, значит исходное число отрицательное.
Решение: <nobr>-2<sub>10</sub></nobr>
, что и требовалось доказать.
P.S. Маленькие циферки справа от числа обозначают систему счисления, если кто не знает. Пример: два в десятичной системе — 210, один‑ноль‑один в двоичной системе — 1012. Кстати, красным цветом выделен знак числа, зелёным — экспонента, а мантисса, соответственно, синим.
Полезные ссылки