преобразовать плавающую точку одинарной точности в плавающую точку половинной точности - PullRequest
3 голосов
/ 05 октября 2019

Я изо всех сил пытаюсь преобразовать 32-битную с плавающей точкой в ​​16-битную с плавающей точкой с C.

Я понимаю концепцию нормализации, денормализации и т. Д.

Но я не смог понять нижеприведенный результат.

Это преобразование соответствует стандарту IEEE 754. (с использованием режима округления до четного)

32bit floating point
00110011 01000000 00000000 00000000 

converted 16bit floating point
00000000 00000001

Это шаг, который я предпринял.

Учитывая, что 32-разрядный бит знака с плавающей запятой равен 0, поле exp равно 102, остаток равенполе битов дроби.

Таким образом, в поле exp 102 должно быть смещение -127, поэтому оно становится равным -25, и оно выглядит следующим образом.

// since exp field is not zero, there will be leading 1.
1.1000000 00000000 00000000 * 2^(-25)

При преобразовании указанного числа в плавающее с половиной точноститочка, мы должны добавить смещение (15) к показателю степени для кодирования поля exp.

поэтому поле exp равно -10.

Так как поле expified меньше 0, учитывая 32-битную плавающую точкуне может быть успешно выражен с плавающей точкой половинной точности.

Так что я думал, что битовая комбинация с плавающей точкой половинной точности будет выглядеть как

00000000 00000000

Но почему 00000000 00000001?

Я прочитал много статей, которые были загружены на stackoverflow, но это всего лишь примеры кода, на самом деле не связанные с внутренним поведением.

Может кто-то, пожалуйста, противоречит моему заблуждению?

1 Ответ

3 голосов
/ 06 октября 2019

Получая смещенную экспоненту -10, вам нужно создать денормализованное число (с 0 в поле экспоненты), сдвигая биты мантиссы вправо на 11. Это дает вам 00000 00000 11000 ... для битов мантиссы,затем вы округляете до 00000 00001 - наименьшее возможное число денорма.


Число IEEE fp имеет 1-битный знак, n-битное поле экспоненты и амбитовое поле мантиссы. Для поля экспоненты n битов значение all 1s представляет Inf или Nan, а значение all 0s представляет denorm или ноль (который зависит от битов мантиссы). Таким образом, только нормалы в диапазоне 1..2 n -2 действительны для нормализованных чисел.

Поэтому, когда вы вычисляете свой показатель "нормализованный и смещенный", если он равен ≤ 0, вынужно генерировать денорм (или ноль) вместо этого. Значение для нормализованного числа:

-1 S (1,0 + 2 -m M) 2 E-bias

(где M - значение в поле мантиссы, рассматриваемое как целое число без знака, а m - количество битов мантиссы - в некоторых описаниях это записывается как 1.M). Значение для денорма составляет

-1 S (0,0 + 2 -m M) 2 1-смещение

То есть показатель степени такой же, как для смещенного значения показателя 1, но «скрытый бит» (дополнительный бит, добавленный к вершине мантиссы) обрабатывается как 0 вместо 1. Таким образом, для преобразования вашего нормализованного числас показателем (смещенным) от -10 до деномра вам нужно сместить мантиссу (включая скрытый 1 бит, который обычно не сохраняется) на 1 - -10 бит (то есть 11 бит), чтобы получить значение мантиссы, которое выхочу за денорм. Поскольку это всегда будет сдвигаться как минимум на один бит (для любой смещенной экспоненты ≤ 0), это сместит 0 в скрытую битовую позицию, что соответствует значению денорм мантиссы. Если показатель степени достаточно мал, он полностью сместится за пределы мантиссы, что даст вам 0 мантиссу (то есть ноль). Но в вашем конкретном случае, даже если он полностью сдвигается из 10 (представимых в формате fp16) битов, защитные биты по-прежнему равны 1 с, поэтому он округляется до 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...