最近一直在深圳华为终端调试我们的算法,唉,几万个大爷,不好伺候,第一次觉得本本分分的在公司呆着做算法或者写代码是多么的幸福。
话说回来,对接的工程师说他们的环境中不可以使用float类型强制转换(事后证明可以使用,只是编译选项的问题),考虑到我的部分算法是必须基于float的,要是改算法的话,动作太大,只有硬着头皮写一个自己的unsigned int转float。
梳理一下记忆,只记得,对于0,float的对应二进制码为0x00000000,(其实是0+,0-的话是0x80000000),然后再就是符号位1位,指数位8位,小数位23位。其他的都忘记了,于是果断网上搜索,找到了一篇C语言浮点数运算,比较清晰。下面大致写写,稍微深入的就去看这篇文章吧。
盗个图。
符号位S,毋庸置疑,肯定是1代表浮点数是负数,0表示浮点数是正数。
而后对这个数的绝对值做一个二进制的科学计数法。随便举个例子:
指数位E,这八位的值为N的话,表示指数部分应该是2的(N-127)次方,即对于上面的例子,指数八位应该是11000111。
小数位F,这儿会隐藏小数部分的唯一一个整数位1,只取小数点后面的部分。
总结为公式就是:
下面上代码。这段代码已经验证0~50000无误,但肯定效率比较低,有待后续优化:
float UI2F(unsigned int x)
{
int i;
int iHighestBitLocation = 0;
int iShiftBitNum = 0;
int iExponentBias = 0;
unsigned int iMemory = 0;
float fResult = 0;
if(0 == x)
{
return fResult;
}
//Find the location of highest bit
for ( i = 31; i >= 0; i--)
{
if (1 == ((x >> i) & 0x1))
{
iHighestBitLocation = i + 1;
break;
}
}
// how many bits should be shift
iShiftBitNum = iHighestBitLocation - 1;
iExponentBias = iShiftBitNum + 127;
for (i = 0; i < 8; i++)
{
if (1 == ((iExponentBias >> i) & 0x1))
{
iMemory = iMemory + (0x1 << (23 + i));
}
}
//get rid of the "1.00000..."
x = x - (0x1 << iShiftBitNum);
for (i = 0; i < iShiftBitNum; i++)
{
if (1 == ((x >> i) & 0x1))
{
iMemory = iMemory + (0x1 << (23 - iShiftBitNum + i));
}
}
memcpy(&fResult, &iMemory, sizeof(float));
return fResult;
}
写这篇文章的时候在想怎么打那几个公式,找到了个在线的latex,的确好用!
最后,真心希望早点回家。。。。