有人可以向我解释如何将32位浮点值转换为16位浮点值吗?

(s =符号e =指数,m =尾数)

如果32位浮点数为1s7e24m
而16位浮点数是1s5e10m

那样做就那么简单吗?

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:糟糕。再次纠结。我想失去前三位而不是低位!那么呢:
fltInt16 =  (fltInt32 & 0x007FFFFF) >> 13;
fltInt16 |= (fltInt32 & 0x0f800000) >> 13;
fltInt16 |= (fltInt32 & 0x80000000) >> 16;

最终代码应为:
fltInt16    =  ((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13);
fltInt16    |= ((fltInt32 & 0x80000000) >> 16);

最佳答案

float32和float16表示形式中的指数可能有偏差,并且有不同的偏差。您需要使从float32表示中获得的指数无偏以获取实际指数,然后将其针对float16表示进行偏置。

除了这个细节,我确实认为就是这么简单,但是我仍然不时为浮点表示感到惊讶。

编辑:

  • 在使用指数做事时检查溢出。
  • 您的算法会突然将螳螂的最后一位截断,这可能是可以接受的,但您可能希望通过查看将要丢弃的位来实现舍入到最近。 “0 ...”->向下舍入,“100..001 ...”->向上舍入,“100..00”->舍入为偶数。
  • 10-06 00:38