赞
踩
文章参考:
http://c.biancheng.net/
https://www.cnblogs.com/jillzhang/archive/2007/06/24/793901.html
C语言中,对于浮点类型的数据采用单精度类型(float)
和双精度类型(double)
来存储,float
数据占用32bit, double
数据占用64bit。无论是单精度还是双精度在存储中都分为三个部分:
其中float
的存储方式如下图所示:
而双精度double
的存储方式为:
符号的存储
符号的存储很容易,就像存储 short、int 等普通整数一样,单独分配出一个位(Bit)来,用 0 表示正数,用 1 表示负数。对于 19.625,这一位的值是 0。
尾数的存储
计算机采用二进制形式存储浮点数,尾数部分的取值范围为 1 ≤ mantissa < 2,这意味着:尾数的整数部分一定为 1,是一个恒定的值,这样就无需在内存中提现出来,可以将其直接截掉,只要把小数点后面的二进制数字放入内存中即可
。对于 1.0011101,就是把 0011101 放入内存。
指数的存储
指数是一个整数,并且有正负之分,不但需要存储它的值,还得能区分出正负号来。
先确定内存中指数部分的取值范围,得到一个中间值,写入指数时加上这个中间值,读取指数时减去这个中间值,这样符号和值就都能确定下来了。
float 的指数部分占用 8 Bits,能表示从 0~255 的值,取其中间值 127,指数在写入内存前先加上127,读取时再减去127,正数负数就显而易见了
。19.625 转换后的指数为 4,4+127 = 131,131 换算成二进制为 1000 0011,这就是 19.626 的指数部分在 float 中的最终存储形式。
19.625 转换成二进制的指数形式为:
19.625 = 1.0011101×24
此时符号为 0;尾数为 1.0011101,截掉整数部分后为 0011101,补齐到 23 Bits 后为 001 1101 0000 0000 0000 0000
;指数为 4,4+127 = 131,131 换算成二进制为 1000 0011。
综上所述,float 类型的 19.625 在内存中的值为:0 - 10000011 - 001 1101 0000 0000 0000 0000。
下面我们通过代码来验证一下:
#include <stdio.h> #include <stdlib.h> //浮点数结构体 typedef struct { unsigned int nMant : 23; //尾数部分 unsigned int nExp : 8; //指数部分 unsigned int nSign : 1; //符号位 } FP_SINGLE; int main() { char strBin[33] = { 0 }; float f = 19.625; FP_SINGLE *p = (FP_SINGLE*)&f; itoa(p->nSign, strBin, 2); printf("sign: %s\n", strBin); itoa(p->nExp, strBin, 2); printf("exp: %s\n", strBin); itoa(p->nMant, strBin, 2); printf("mant: %s\n", strBin); return 0; }
运行结果:
sign: 0
exp: 10000011
mant: 111010000000000000000
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。