前阵子有门课的作业让写出几个浮点数的IEEE 754 单精度形式,有的数很不规则,23个尾数都得算,于是就写了个程序。先判断正负,小于零则符号位为1,否则为0. 然后对它的绝对值以2为底取对数,再取下整,加上127为8位指数部分的无符号数。最后算23位尾数。程序写出来了:
void ieee754_alg(char* bits, float num)
{
int exp;
int i;
int temp;
float tail;
float b = 1;
if (num >= 0)
bits[0] = 0;
else
{
bits[0] = 1;
num = -num;
}
exp = floor(log(num)/log(2)) + 127;
tail = num / pow(2, exp - 127) - 1;
for (i = 7; i >= 0; i--)
{
temp = pow(2, i);
if (exp >= temp)
{
exp = exp - temp;
bits[8 - i] = 1;
}
else
bits[8 - i] = 0;
}
for (i = 1; i <= 23; i++)
{
b /= 2;
if (tail >= b)
{
tail = tail - b;
bits[8 + i] = 1;
}
else
bits[8 + i] = 0;
}
}
bits是个长度为32的字节数组。再复杂的数,一下就算出来了,很爽。但最近又想了一下,这种办法实在是太傻了,我们一般计算机里面不就是用IEEE 754表示浮点数的吗?把内存里面的位取出来就行了。程序如下,注意要考虑到一般的计算机都是little-endian,高字节在高地址。
void ieee754_mem(char* bits, float num)
{
char* addr = (char*)#
char byte;
int i, j, k = 0;
for (i = 3; i >= 0; i--)
{
byte = *(addr+i);
for (j = 7; j >= 0; j--)
{
bits[k++] = (char)((byte >> j) & 0x1);
}
}
}
这样就省力多了。