Форматы float32 и double64 на пальцах
Вкратце, идея довольна простая: исходное число необходимо привести к нормализованному виду
в двоичной системе счисления с помощью битового сдвига, затем записать дробную часть этого числа в мантиссу, а количество сдвигов в экспоненту. И завершающим штрихом сохранить знак исходного числа.
Формат float32 имеет такой вид: 1s8e23m
, где s — количество бит под знак, e — экспонента, m — мантисса. Для формата double64 вид такой — 1s11e52m
.
Первый бит кодирует знак числа. Если это ноль, число положительно, в противном случае число отрицательное.
Затем идут восемь бит экспоненты. Если совсем простыми словами, то экспонента — это количество сдвигов запятой в исходном числе, представленном в двоичном виде, для получения нормализованного числа вида
. Чтобы получить количество сдвигов из этих восьми бит надо отнять
. Отрицательная экспонента — сдвиг влево, положительная — сдвиг вправо.
После экспоненты следуют 23
бита мантиссы. Это дробная часть числа
.
А теперь практическая часть!
Перевод десятичной дроби во float32
Попробуем с полученными знаниями закодировать число
.
В двоичном виде это число имеет вид
. Для получения нормализованного числа необходимо запятую сдвинуть влево на один разряд. Получим число
и экспоненту равной 1
.
Для сохранения экспоненты к ней надо прибавить
. Получится
или
в двоичном виде.
Берем нормализованное число
и выделяем мантиссу
. Для сохранения этого числа, которое занимает 4 бита, надо добавить нули справа до 23 бит. Получится число
.
Знак числа отрицательный, значит первый бит равен единице.
Итог: s=
e=
m=
, с чем я вас и поздравляю.
Обратный перевод: из float32 в число
Разберем пример из википедии. Есть число во float32
. В двоичной системе это будет 110000000000000000000000000000002
.
Разобъем его на компоненты: s=
e=
m=
.
Мантисса равна нулю, но, как уже было сказано выше, сохраняется только дробная часть мантиссы, а единица отбрасывается. Значит мантисса равна
.
Экспонента равна
или
, отнимаем
и получается, что экспонента равна единице.
Возьмем мантиссу и сдвинем точку вправо на эту единицу, получится
, это
в десятичной системе счисления.
Знак числа равен единице, значит исходное число отрицательное.
Решение:
, что и требовалось доказать.
P.S. Маленькие циферки справа от числа обозначают систему счисления, если кто не знает. Пример: два в десятичной системе —
Полезные ссылки
- видео «Как работают числа с плавающей точкой» с канала Alek OS (рекомендую к просмотру)
- подробное описание формата IEEE754 на русском языке
- онлайн калькулятор для перевода десятичных дробей в двоичные
Попробуем с полученными знаниями закодировать число -2.62510.
В двоичном виде это число имеет вид 10.1012. Для получения нормализованного числа необходимо запятую сдвинуть влево на один разряд. Получим число 1.01012 и экспоненту равной -1.(с)
Какая в дупло экспонента «-1» ?! Просто единица.
Согласен, моя ошибка. Фраза про дупло — явно лишняя в вашем комментарии. Не думал, что математики столь агрессивны )
За экспоненту и двор стреляю в упор