IEEE754浮点数的学习笔记
格式 长度 符号位 指数位 尾数位 有效位数 指数偏移 尾数说明
单精度 32 1 8 23 24 127 有一位隐含位
双精度 64 1 11 52 53 1023 有一位隐含位
扩展双精度 80 1 15 64 64 16383 没有隐含位
注意:扩展双精度格式没有隐含位,因此它的有效位数与尾数位数一致,而单精度和双精度格式均有一位隐含位,因此它们的有效位数比尾数位数多1。
单精度格式浮点数表示范围
指数 尾数 数值(二进制) 数值(十进制)
最大数 0xfe 0x7fffff 1.(23个1) * 2^(+127) 3,4028236692093846346337460743177e+38
最小数 0x1 0x0 1.(23个0) * 2^(-126) 1,1754943508222875079687365372222e-38
最小弱规范数 0x0 0x1 0.(22个0)1 * 2^(-126) 1,4012984643248170709237295832899e-45
注意:弱规范数的隐含位是0。
双精度格式浮点数表示范围
指数 尾数 数值(二进制) 数值(十进制)
最大数 0x7fe 0xfffffffffffff 1.(52个1) * 2^(+1023) 1,797693134862315907729305190789e+308
最小数 0x1 0x0 1.(52个0) * 2^(-1022) 2,2250738585072013830902327173324e-308
最小弱规范数 0x0 0x1 0.(51个0)1 * 2^(-1022) 4,9406564584124654417656879286822e-324
注意:弱规范数的隐含位是0。
扩展双精度格式浮点数表示范围
指数 尾数 数值(二进制) 数值(十进制)
最大数 0x7ffe 0xffffffffffffffff 1.(63个1) * 2^(+16383) 1,189731495357231765085759326628e+4932
最小数 0x1 0x8000000000000000 1.(63个0) * 2^(-16382) 3,3621031431120935062626778173218e-4932
最小弱规范数 0x0 0x1 0.(62个0)1 * 2^(-16382) 3,6451995318824746025284059336194e-4951
注意:扩展双精度格式数没有隐含位,第63位(尾数最高位)表示整数位。
附:测试代码(vc 6.0下通过)
#include <stdio.h>
typedef struct FP_SINGLE
{
unsigned __int32 fraction : 23;
unsigned __int32 exp : 8;
unsigned __int32 sign : 1;
} fp_single;
typedef struct FP_DOUBLE
{
unsigned __int64 fraction : 52;
unsigned __int64 exp : 11;
unsigned __int64 sign : 1;
} fp_double;
typedef struct FP_EX_DOUBLE
{
unsigned __int64 fraction;
unsigned __int32 exp : 15;
unsigned __int32 sign : 1;
} fp_ex_double;
int main()
{
float x;
fp_single * fp_s = (fp_single *)&x;
fp_s->sign = 0;
fp_s->exp = 0xfe;
fp_s->fraction = 0x7fffff;
printf ("float 最大数: %le\n",(double)x);
fp_s->sign = 0;
fp_s->exp = 0x1;
fp_s->fraction = 0x0;
printf ("float 最小数: %le\n",(double)x);
fp_s->sign = 0;
fp_s->exp = 0;
fp_s->fraction = 0x1;
printf ("float 最小弱规范数:%le\n\n",(double)x);
double y;
fp_double * fp_d = (fp_double *)&y;
fp_d->sign = 0;
fp_d->exp = 0x7fe;
fp_d->fraction = 0xfffffffffffff;
printf ("double 最大数: %le\n", y);
fp_d->sign = 0;
fp_d->exp = 0x1;
fp_d->fraction = 0x0;
printf ("double 最小数: %le\n", y);
fp_d->sign = 0;
fp_d->exp = 0;
fp_d->fraction = 0x1;
printf ("double 最小弱规范数:%le\n\n", y);
char ch[10];
fp_ex_double * fp_ex_d = (fp_ex_double *)ch;
fp_ex_d->sign = 0;
fp_ex_d->exp = 0x7ffe;
fp_ex_d->fraction = 0xffffffffffffffff;
// 不知道扩展双精度浮点数如何输出,
// 不过可以用od跟踪,然后找到ch[0]的地址,在数据窗口中选择 浮点 80为长双精度,
// 就可以看到数值了。
fp_ex_d->sign = 0;
fp_ex_d->exp = 0x1;
fp_ex_d->fraction = 0x8000000000000000;
fp_ex_d->sign = 0;
fp_ex_d->exp = 0;
fp_ex_d->fraction = 0x1;
return 0;
}