问题源于printf函数的%x格式,无法反映浮点数在内存中的二进制存储
下面用C的联合体和位段,分析浮点数在内存中的二进制存储格式,纯属好奇,当作练习:)
首先,收集浮点数的相关知识
维基百科,阅读以下两篇文章
Location: http://zh.wikipedia.org/wiki/%E6%B5%AE%E7%82%B9%E6%95%B0
浮点数
Location: http://zh.wikipedia.org/wiki/IEEE_754
IEEE 754
获知单精度32位浮点数的格式,如下

参考以上资料,使用C语言的联合体和位段,编写程序,运行如下
$ cat main.c #include <stdio.h> union { float a; unsigned int b; } ex; struct float_32_format { unsigned int fraction: 23; /* 有效数位 */ unsigned int exp: 8; /* 指数位 */ unsigned int sign: 1; /* 符号位 */ }; /* 倒序表示 */ void analysis(float val) { struct float_32_format *format; printf("--- 开始分析浮点数 %f\n",val); ex.a=val; printf("-- 单精度浮点数存储的4个字节,10进制表示: %u\n",ex.b); printf("-- 单精度浮点数存储的4个字节,16进制表示: 0x%X\n",ex.b); /* 妙用union */ format=(struct float_32_format*)(&ex.a); /* ex.a或ex.b皆可 */ printf("-- sign: %u\n",format->sign); printf("-- exp: %u\n",format->exp); printf("-- fraction: %u ( 0x%X )\n",format->fraction,format->fraction); printf("\n"); } int main() { printf("'float' size: %d\n",sizeof(float)); printf("'unsigned int' size: %d\n\n",sizeof(unsigned int)); analysis(-20.25); return 0; } $ cat Makefile all: gcc main.c clean: rm -f a.out *~ $ ls main.c Makefile $ make gcc main.c $ ./a.out 'float' size: 4 'unsigned int' size: 4 --- 开始分析浮点数 -20.250000 -- 单精度浮点数存储的4个字节,10进制表示: 3248619520 -- 单精度浮点数存储的4个字节,16进制表示: 0xC1A20000 -- sign: 1 -- exp: 131 -- fraction: 2228224 ( 0x220000 ) $ |
分析程序输出的数据
sign=1, 为负数
exp=131, 131-127=4
fraction=0x220000, 二进制表示: 010 0010 0000 0000 0000 0000 (23位)
整合起来:
- 1.010 0010 0000 0000 0000 0000 x 2^4
- 1010 0.010 0000 0000 0000 0000
符号部分 负数
整数部分 10100 = 1x2^4 + 1x2^2 = 16+4 = 20
小数部分 0.010 = 1x2^-2 = 0.25
综上所述,单精度浮点数存储的4个字节,16进制表示0xC1A20000,即为浮点数-20.25
Q.E.D.
读<<C和指针>>,新年回家复习C语言,准备找工作了
时间:2010-01-24 17:35
来源:Linuxeden
作者:c-aries
原文链接