Float32 к Float16

Кто-то может объяснить мне, как я преобразовываю 32-разрядное значение с плавающей точкой в 16-разрядное значение с плавающей точкой?

(s = знак e = экспонента и m = мантисса)

Если 32-разрядное плавание составляет 1s7e24 м
И 16-разрядное плавание составляет 1s5e10 м

Затем действительно ли это столь же просто как выполнение?

int     fltInt32;
short   fltInt16;
memcpy( &fltInt32, &flt, sizeof( float ) );

fltInt16 = (fltInt32 & 0x00FFFFFF) >> 14;
fltInt16 |= ((fltInt32 & 0x7f000000) >> 26) << 10;
fltInt16 |= ((fltInt32 & 0x80000000) >> 16);

Я предполагаю, что это НЕ настолько просто..., таким образом, кто-либо может сказать мне, что ДЕЙСТВИТЕЛЬНО необходимо сделать?

Править: Я бегунок видит, что у меня есть свой сдвиг экспоненты неправильно..., таким образом, ЭТО было бы лучше?

fltInt16 =  (fltInt32 & 0x007FFFFF) >> 13;
fltInt16 |= (fltInt32 & 0x7c000000) >> 13;
fltInt16 |= (fltInt32 & 0x80000000) >> 16;

Я надеюсь, что это корректно. Извинения, если я пропускаю что-то очевидное, это было сказано. Почти полночь в пятницу ночью..., таким образом, я не являюсь "совершенно" трезвым ;)

Редактирование 2: Ooops. Занятый содомией это снова. Я хочу потерять лучшие 3 бита не ниже! Таким образом как насчет этого:

fltInt16 =  (fltInt32 & 0x007FFFFF) >> 13;
fltInt16 |= (fltInt32 & 0x0f800000) >> 13;
fltInt16 |= (fltInt32 & 0x80000000) >> 16;

Заключительный код должен быть:

fltInt16    =  ((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13);
fltInt16    |= ((fltInt32 & 0x80000000) >> 16);
8
задан Goz 10 March 2014 в 23:20
поделиться

2 ответа

Показатели степени в ваших представлениях float32 и float16, вероятно, смещены и смещены по-разному. Вам нужно откорректировать показатель степени, который вы получили из представления float32, чтобы получить фактический показатель степени, а затем отрегулировать его для представления float16.

Если не считать этой детали, я думаю, что это так просто, но меня все равно время от времени удивляют представления с плавающей запятой.

РЕДАКТИРОВАТЬ:

  1. Проверяйте переполнение, когда делаете что-то с экспонентами, пока вы на нем.

  2. Ваш алгоритм немного резко обрезает последние биты мантисы, что может быть приемлемо, но вы можете реализовать, скажем, округление до ближайшего, глядя на биты, которые собираются отбросить. «0 ...» -> округлить в меньшую сторону, «100..001 ...» -> округлить в большую сторону, «100..00» -> округлить до четного.

4
ответ дан 5 December 2019 в 12:56
поделиться

Вот ссылка на статью о IEEE754, в которой приведены схемы расположения битов и смещения.

http://en.wikipedia.org/wiki/IEEE_754-2008

4
ответ дан 5 December 2019 в 12:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: