首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >浮点数(float)类型数据在内存中的存储规则

浮点数(float)类型数据在内存中的存储规则

作者头像
再睡一下就好
发布2025-06-10 17:06:25
发布2025-06-10 17:06:25
1.3K0
举报

前言

不知道读者在刚接触编程时有没有想过 将 int型数据 按浮点数类型打印会怎样,如下代码:

int x = 7;

printf("%d ", x); printf("%f", x);

在不理会编译器提醒的情况下,得到的结果:一个是7,一个是0.000000。

Why?

一、浮点数在内存中的存储和读取规则

1.浮点数,包括float、double、long double等类型,根据国际标准规定,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:

V = (−1)^S ∗ M ∗ 2^E;F

(1)(−1)^S 表示符号位,当VS=0时,F表示正数;当S=1时,F为负数。

(2)M为有效数字,为1<=M<2之间;

(3)2^E表示位数。

2.占用内存情况:S符号占1个二进制位,接着是E占8个二进制位(如果是64位浮点数则占11位),再然后才是M占23位二进制位(如果是64位浮点数占52位)。

3.存储规则:

(1)M:由于浮点数已经写成二进制形式,故1<=M<2,当编译器存储M时会把整数部分的1省略掉,全部用来存取小数点后的位数,在读取时自动加上1,这样做的目的是为了增加精度

(2)E:由于在科学计数法中指数也是有负数形式的,以在E中存储的值会加上127(或1023)以便存储负数形式的指数,再存储在内存中。

4.读取规则:

(1)E中不全为0或不全为1:先将E中存储的数值减去127(或1023)得到真实值,再把M中的值填充到“1.”之后,最后依据公式得出该数的二进制形式,最后转换为十进制数。

(2)E中全为0:如果再减去127后的得到的真实值非常小,故此时计算机不再将M中的1加入,直接将M中的值加到“0.”后,以表示±0,或接近0的数。

(3)E中全为1:此时再看M中的值,若全为0则表示为无穷大(小),若不是就按正常“E中不全为0或不全为1”还原。

二、举列

现在我们站在float的视角,看看前言中的int x按照“%f”类型是怎么打印的。

int x = 7;

x为正数在内存中按二进制方式存储:00000000 00000000 00000000 00000111,

现在我们站在float的视角读取内存中的内容:

先取第一位S位,为0,故该数是个整数。

再取8位E,全为0,M不加1,则该数为0.xxx的形式。

最后取剩下的23位M还原为十进制后,直接加到小数点后

还原成公式形式:V=(-1)^0 * 0.00000000000000000000111 * 2^0 ,换算成十进制后再取前6位(32位浮点数形式),打印出的必然是0.000000.

再举列float y = 0.5:

由于存储规则,整数部分必须为1,所以化为二进制后为1.0 * 2^(-1),则S=0,E=-1(126的二进制011111110),M=1;

即为0 01111110 00000000000000000000000(别忘了编译器会自动加上1),因在vs中地址采用16进制编码,故该二进制转十六进制为 3F 00 00 00,在vs调试内存窗口中可以看到为0x000000B1142FF7B4 00 00 00 3f。

(为什么存储顺序不同可参看文章”)。

再举列-5.0,写成二进制数为-101,相当于- 1.01×2^2 ,按照公式可写为(-1)^1 * 1.01 * 2^2,故S=1,M=1.01,E=2。

“纸上得来终觉浅”,还是得动手敲一敲才能彻底明白、吸收。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、浮点数在内存中的存储和读取规则
  • 二、举列
    • 现在我们站在float的视角,看看前言中的int x按照“%f”类型是怎么打印的。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档