浮点数在内存中的存取

浮点数家族的三个类型有float,double,long double,他们在内存中的存储方式和整型有着本质上的区别。

首先我们通过一个例子来引出悬念:

int main()
{
    int n = 9;
    float* pFloat = (float*)&n;
    printf("n=%d\n", n);
    printf("*pFloat=%f\n", *pFloat);

    *pFloat = 9.0;
    printf("num=%d\n", n);
    printf("*pFloat=%f\n", *pFloat);
    return 0;
}

如果我们在不知道浮点型在内存中的存储细节时,我们不难得到以下错误的结果:

9 9.000000 9 9.0000

但是真正的结果是多少?让我们看下边这张图:

错的有点离谱,下面开始分析:

浮点数在内存中的存储是按照公式:(-1)^S*M*2^E 来存储的,

(-1)^S表示的是符号位

M表示有效数字

E表示指数位

在32位机器上,第1位表示符号位,即(-1)^S;第2~9位表示指数位,也就是E;后面的23位表示的是有效数字M。而64位机器上,第1位表示符号位,第2~12位表示指数位,剩下52位表示有效数字。

  • 符号位用0和1表示,浮点数为正则是1,反之则为0.

  • 指数位大小,相当于将一个浮点数的二进制形式移动小数点直到范围为1~2时所移动的位数加上一个补偿数,例如十进制的3.25,变为二进制得到11.01,转换为科学计数法的形式就是1.101*2^1,这里的1要加上一个补偿数,在32位计算机上加127,在64位计算机上加1023,这里的E以32位计算机为例,值为1+127得到128。

  • M就是浮点数二进制形式经过科学计数法表示得到的有效数字,也就是上面例子的1.101,但是在内存中,是不存储首位整数位的1的,计算机默认该整数位的值为1,不存储,在读取时再将1加上去.这样就可以多保存一位小数位,提高了精度.

知道了浮点数在内存中的存储,我们试着理解最上面的题:

首先创建一个n的整型变量:

int n=9

我们以%d打印一点得到9;

printf("*pFloat=%f\n", *pFloat);

当我们创建一个float类型的指针变量*pFloat,然后将地址n处的值强制转换为float类型存储在该变量中,以%f打印时:

00000000000000000000000000001001

指数位全为0,当E全为0时,代表该数无限趋近于0,因此打印得到结果为0.000000

    *pFloat = 9.0;
    printf("num=%d\n", n);

我们将*pFloat的值改为9.0,此时在内存中是按照浮点数的方法存储的,也就是

01000001000100000000000000000000

我们以整型%d打印,该值也就是1091567616

printf("*pFloat=%f\n", *pFloat);

最后,我们以浮点型%f打印浮点数,就正确得到了9.000000

浮点型的主要部分就是这样,这里有几种特殊情况还需要加以说明:

  • 当E为全0时,代表该浮点数趋近于无穷小

  • 当E为全1时,代表该浮点数趋近于+/-无穷大.

如果该文章对你有所帮助,还请点赞支持一下.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

S+叮当猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值