16位浮点数

地球人都知道现在的dx内部都开始支持16位的浮点了, also known as float16(half)
这种类型本身并不是标准IEEE里的,不同的平台也有不同的实现方法。
就偶这几天hardcore Xenon的程序来看,dx内部的16位float结构如下:
|0100 0010 0010 0100|
 s
   |exp|
           | mantissa  |
假设0100 0010 0010 0100是一个16位的浮点数,那么从高位的第一位仍然是sign位
然后有4位的exp和11位的mantissa。
4位的exp是直接截低4位就ok了
mantissa则是截高11位,这点需要注意,模拟的c/c++ code如下:
u16 tofloat16(float f)
{
u32 *i = (u32 *)&f;
u32 sign = (*i >> 31) & 0x1;
u32 exponent = ((*i >> 23) & 0xff) - 0x7f;
u32 mantissa = (*i) & 0x7fffff;

exponent += 0x7;
u16 ret = ((sign & 0x1) << 15);
ret |= (exponent & 0xf) << 11;
ret |= (mantissa  >> 13) & 0x7ff;
return ret;
}

 

u32 tofloat32(u16 f)
{
u16 *i = (u16 *)&f;
u32 sign = (*i >> 15) & 0x1;
u32 exponent = ((*i >> 11) & 0xf) - 0x7;
u32 mantissa = (*i) & 0x7ff;

exponent += 0x7f;
u32 ret = ((sign & 0x1) << 31);
ret |= (exponent & 0xff) << 23;
ret |= (mantissa << 13) & 0x7fffff;
return ret;

首先,16浮点数通常被表示为符号(1)、指数(5)和尾数(10)。因此,需要确定浮点数的符号、指数和尾数。 1. 确定符号 由于0.0004125是一个正数,所以符号为0。 2. 确定指数 首先需要将0.0004125转换为科学计数法的形式: 0.0004125 = 4.125 x 10^(-4) 由此可知指数为-4。由于指数需要加上一个偏移量,通常是2^(k-1)-1,其中k是指数数,因为这里k=5,所以偏移量为15。因此,将-4加上15得到11,即指数为1011。 3. 确定尾数 尾数的计算需要将4.125规范化为二进制小数。首先将整数部分4转换为二进制,得到100。然后将小数部分0.125乘以2,得到0.25,取整得到0,再将0.25乘以2,得到0.5,取整得到1,再将0.5乘以2,得到1,取整得到1,因此小数部分的二进制表示为0.001。将整数部分和小数部分拼接起来,得到100.001。 由于尾数需要10,因此需要将100.001舍入为10。舍入方式通常有以下几种: - 就近舍入:将最后一四舍五入到离它最近的整数。 - 向零舍入:将最后一直接截断。 - 向上舍入:将最后一加1,然后向零舍入。 - 向下舍入:将最后一减1,然后向零舍入。 这里我们采用就近舍入。最后一是1,它前面的是001,因为它小于0.5,所以将最后一舍去,得到尾数为1000010000。 综上所述,浮点数0.0004125的16浮点数表示为: 0 1011 1000010000
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值