前阵子有门课的作业让写出几个浮点数的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); } } }
这样就省力多了。
Leave a Reply