float – 单精度,占用4个字节的空间。
char – 字符型,占用1个字符的空间。
一个float可转换为4个char型表示。
第一种方法,最简单的方法:
union float_type { float f; char s[4]; };
注意数据存储的方向性(即大小端问题)。
例如:
在小端上: 浮点数3.750000表示为 0x40980000
则s[3] =0x40; s[2] = 0x98; s[1] = s[0] = 0; 然后 f = 3.750000
在大端上反之
问题至此结束,没有任何问题,然而个人比较贱,喜欢装B,加上看过一些浮点表示法的书籍,对使用IEEE 754方法来转换跃跃欲试,那么问题来了。
跟据格式编写代码如下:
voidchar2float(char *s, float *f) { int flag, exp; flag = (s[0] & 0x80) ? (-1) : 1; exp = ((s[0] & 0x7f) << 1) + (1 & (s[1] >> 7))– 127; *f = (float) ( flag * 1.0 * ( (1 <<23) + ((s[1] & 0x7f) <<16) + (s[2] << 8) + s[3] ) / (1 <<(23 - exp))); }
运行,得出0x40980000就是3.750000
哈哈,可是当输入0x00000000后,有点不对劲啊,怎么输出2.000000呢?
不妙啊,看我的凌波微步,各种飘移。怎么会错呢?
后来,我终于明白了,如何去。。。
左看看右看看,只能出现在(1 << (23 - exp))上了,当我换上pow(2.0, 23-exp)后问题就好了。
然后我就百度一下移位运算符:
在移位运算时,byte、short和char类型移位后的结果会变成int类型,对于byte、short、char和int进行移位时,规定实际移动 的次数是移动次数和32的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和64的余数,也就是 移动66次和移动2次得到的结果相同。
所以(1<< 23) / (1 << 150) = (1<<23)/(1<<22) = 2.000000
那么问题解决了吗?
本文出自 “三足乌” 博客,谢绝转载!
原文地址:http://lzwbk.blog.51cto.com/3720506/1826390