您的位置:首页 > 其它

ieee浮点

2015-10-18 19:28 281 查看
IEEE浮点标准用符号位、有效数、指数位来表示一个数

符号位:决定是负数(s=1)还是正数(s=0)

有效数:无符号二进制小数(exp)

指数位:2的幂(frac可能为负数),加权

在单精度浮点浮点格式(C语言中的float)中,s、exp、frac域分别为1位、8位、23位,产生一个32位的表示。在双精度浮点格式(C语言中的double)中,s、exp、frac域分别为1位、11位、52位,产生一个64位的表示。

规格化值:exp域不是全0全1, 小数域frac描述小数值f(0<=f<1),有效数定义为M = 1 + f,既然第一位始终为1,我们就不需要显式表示它(隐含的以1开头的表示)

如,若要表示1.5,二进制就是1.1 ==> 0.1*2^0

对于小数位:0.1 即 100 0000 0000 0000

对于指数位:0 偏置形式的有符号数 x - 2^(8-1) = 0, 求得x = 127 即 0111 1111

程序验证:

#include <stdio.h>
#include <stdlib.h>

//模拟小端数据
typedef struct stFloat
{
int frac:23;
int exp:8;
int s:1;
}ST_FLOAT;

int main(int argc, char *argv[])
{
float f;
ST_FLOAT stF;
stF.s = 0;
stF.exp = 0x7f; // 0111 1111
stF.frac = 0x400000; // 0100 0000 0000 0000
f = *(float*)(&stF);
printf("%f\n", f);

return 0;
}

[dell@localhost C]$ gcc -o ieee ieee.c
[dell@localhost C]$ ./ieee
1.500000

非规格化值:指数域全为0,这种情况指数值是1-[2^(8-1)-1] = -126,有效位的值M=f,不包含隐含的1

1)提供了一种表示值0的方法
2)表示那些非常接近于0.0的数,对“逐渐溢出”属性的支持

#include <stdio.h>
#include <stdlib.h>

//模拟小端数据
typedef struct stFloat
{
int frac:23;
int exp:8;
int s:1;
}ST_FLOAT;

int main(int argc, char *argv[])
{
float f;
ST_FLOAT stF;
stF.s = 0;
stF.exp = 0x0;
stF.frac = 0x400000;
f = *(float*)(&stF);
printf("%.42f\n", f);

return 0;
}

二进制126位相当于八进制42位,因此十进制42位有效位我们一定可以看到0.00 05的出现,看输出吧

[dell@localhost C]$ gcc -o ieee ieee.c
[dell@localhost C]$ ./ieee
0.000000000000000000000000000000000000005877

按说,5后面都应该是0。这个输出也暴露出浮点数的不精确的特点

特殊数值:指数域全为1,看程序吧

#include <stdlib.h>

//模拟小端数据
typedef struct stFloat
{
int frac:23;
int exp:8;
int s:1;
}ST_FLOAT;

int main(int argc, char *argv[])
{
float f;
ST_FLOAT stF;
stF.s = 0;
stF.exp = 0xff;
stF.frac = 0x0;
f = *(float*)(&stF);
printf("%.42f\n", f);

stF.frac = 0x1; //小数位不是全0
f = *(float*)(&stF);
printf("%.42f\n", f);

return 0;
}

输出如下:

[dell@localhost C]$ ./ieee
inf
nan

这两个符号,我们应该见过,第一个表示无穷大,第二个表示实数和无穷以外的数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: