【发布时间】:2011-03-02 20:54:17
【问题描述】:
有人可以向我解释一下如何将 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:糟糕。又搞砸了。我想失去前 3 位而不是低位!那么这个怎么样:
fltInt16 = (fltInt32 & 0x007FFFFF) >> 13;
fltInt16 |= (fltInt32 & 0x0f800000) >> 13;
fltInt16 |= (fltInt32 & 0x80000000) >> 16;
最终代码应该是:
fltInt16 = ((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13);
fltInt16 |= ((fltInt32 & 0x80000000) >> 16);
【问题讨论】:
-
我认为这已经被问到(并回答)了:stackoverflow.com/questions/1659440/…
-
它可能就这么简单,但是除非 float32 不使用它所拥有的所有“精度”,否则你会失去精度......基本上,你得到 exp 的 5/7 位(你当然拿最重要的)和尾数的 10/24;这些比率以某种方式说明了您可以在转换中损失多少。如果您想将 32 位整数放入 16 位整数中,情况完全一样……可表示数字的范围更小; “切割”尾数会降低“精度”,指数也限制了范围:5个有符号位给出-16到+15,反对-64/+63(如果我做得对......:D晚了)
-
@ShinTakezou:当然不可能丢失 16 位数据而不丢失精度?? Float16 的精度要低得多,因此精度会自动降低……还是我误解了你?
-
您可以松开 16 位并让“float16”代表“精确”相同的 float32 数字,只需“选择”float32 数字以便它发生......但通常可以'不选择,所以大多数时候发生的事情是丢失信息。换句话说,您可以将任何 float16 数字(提供相同的约定)放入 float32 并再次“返回”到 float16 没有任何损失(f16 > f32 不会“发明”“精度”,因此 f16 > f32 > f16' 可以这样做是为了 f16' === f16)
标签: c floating-point