【C语言】浮点数在内存中的存储和读取——底层分析

这篇具有很好参考价值的文章主要介绍了【C语言】浮点数在内存中的存储和读取——底层分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🚀write in front🚀
🔎大家好,我是gugugu。希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
🆔本文由 gugugu 原创 CSDN首发🐒 如需转载还请通知⚠
📝个人主页:gugugu—精品博客
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​
📣系列专栏:gugugu的精品博客
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言

前言

整数在内存中以二进制补码的形式存储,这个相信大家都很熟悉,那么浮点数又是怎么在内存中存储的呢?这篇博客将给大家详细讲解。
【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言

一、一道有意思的题目

#include <stdio.h>
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;
}

首先我们从这个题目引入

仔细去思考一下,这个题目将会输出什么?

答案还是比较奇怪的

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言
为什么 会输出0.000000
又为什么会输出1091567616这么大的数字呢?

在学习完本章博客之后,就能够明白这道题目。

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言

二、浮点数的存储

1、存储规则

根据国际标准IEEE(电气和电子工程协会) 754,任意⼀个⼆进制浮点数V可以表示成下面的形式:
V = (−1) S * M * 2E
• (−1)S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
• M 表示有效数字,M是大于等于1,小于2的
• 2E 表示指数位

看着是不是很懵圈?
【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言

没关系,博主先举几个例子

首先先说5.5
5.5 = 101.101?

  • 是不是很多小伙伴会这么写? 哈哈,我猜对了吧,实际上这么写是错误的,
  • 因为2进制每一位都有权重 小数点后面第一位的权重是2-1 = 0.5
  • 所以 , 5.5=101.1
  • 又M大于等于1,小于2, 所以101.1=1.011 * 102?
  • 又错了, 注意,这里是二进制浮点数,不是10进制
  • 所以 101.1=1.011 * 22
  • S呢?S怎么处理
  • 因为5.5是正数,所以S=0

至此 5.5 = (-1)0 * 1.011 * 22

所有的浮点数都可以这么写,各位小伙伴可以自己举几个例子试试吧,当然,别太复杂,否则自己会写吐的。

2、在内存中的占位

IEEE754标准还规定
对于32位的浮点数(float),最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M

如下图

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言

对于64位的浮点数(double),最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

如下图

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言

三、浮点数在内存中存储的具体实现

1、对于S

因为-1的0次方等于1,即正数,-1的1次方等于-1,即负数
所以S中只用存储0或者1就可以完成符号的区分。

2、对于M

因为M大于等于1,小于2,所以M都是一点几,
既然都相同,那就可以不用去存储了,直接去存储小数点后面的数字就可以了。

这样做有什么好处呢???

很显然,这样子做就可以省下储存1的那个比特,可以多储存一个二进制位。
从而提高了浮点数的精度。

3、对于E

首先规定了E为无符号整形。
因为可能出现负指数,所以IEEE754标准中提到一个词——中间数,
指数加上这个中间数,就变成了非负整数。

  1. 对于32位,E的范围是0~255,中间数就是127
  2. 对于64位,E的范围是0~2047,中间数就是1023

所以,前面提到的5.5,在内存中存储的就是
S=0, E=2+127=129=10000001,M=011,因为未占满,所以后面全部补0,所以
M=01100000000000000000000

四、浮点数读取的过程的具体实现

浮点数读取有三种情况

a、第一种情况

当E中既有0又有1时,这是,就是正常情况,根据存储的过程反向操作就行。

b、第二种情况

当E中全部都是0的时候,
E的真实值会分成非常小,这个时候,这个浮点数也就是会非常非常小,非常接近于0。
编译器就会将E=1-127或者1-1023,注意是1减,而不是0减。
然后M不会在小数点前面重新加上1.了,而是直接变成0.xxxxxx
通过这些操作来表示0或者一个十分接近0的浮点数。

c、第三种情况

当E中全部都是1的时候,
这时,即使M中的数字为0时,也表示正无穷或者负无穷,即一个超级大或者超级小的数字。

好啦,到这里,浮点数的存储规则讲解的差不多了,现在,我们可以来分析在最开始提出的那个题目了。

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言

五、解决题目

#include <stdio.h>
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。
    注意这里是按照整形去存储的,所以,内存空间中存储的是(以小端机器16进制来写)09 00 00 00
    所以打印n 的时候是9
  • 接着将n的地址强制类型转换成一个浮点数指针,赋值给了pFloat
    先写成二进制吧
    0000 1001 0000 0000 0000 0000 0000 0000
    此时,按照浮点数的读取规则,E的真实值是18-127=-109,M=1.0
    所以pFloat=1.0* 2-109,非常非常小,且按照%f去打印,%f只打印6位小数,很显然,这个数的前六个小数位全部是0,所以,最终打印的是0.000000
  • 接着,通过指针指向n的空间,将内存存储的9以浮点数的形式改写成了9.0
    9.0以浮点数的存储方式,存储的是(-1)0 * 1.001 * 23
    所以S=0,E=3+127=130,M=00100000000000000000000
    所以32位二进制里面存储的应该是
    01000001000100000000000000000000
    以%d 十进制整形的方式读取,答案就是

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言
1091567616
【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言
与答案相同

  • 最后以浮点数的方式打印9.000000

所以四个答案都得到了很好的解释。



okok,今天第二更奉上,关于浮点数的存储是C语言里面的一处比较重要的底层理解,希望大家能够学到不少东西吧。


!!!!!!!!!!!!!!!!!求关注!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!蹲个一键三连!!!!!!!!!!!!!!!

【C语言】浮点数在内存中的存储和读取——底层分析,技术栏,博客创作,小白教学,c语言文章来源地址https://www.toymoban.com/news/detail-722479.html

到了这里,关于【C语言】浮点数在内存中的存储和读取——底层分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • C语言——数据在内存中的存储

    C语言——数据在内存中的存储

    本章重点 1. 数据类型详细介绍 2. 整形在内存中的存储:原码、反码、补码 3. 大小端字节序介绍及判断 4. 浮点型在内存中的存储解析 目录 1. 数据类型介绍 1.1 类型的基本归类 2. 整形在内存中的存储 2.1 原码、反码、补码 2.2 大小端介绍 2.3 练习 2.4 unsigned char 和 signed char的区别

    2024年02月08日
    浏览(15)
  • 数据在内存中的存储(C语言)

    数据在内存中的存储(C语言)

    ​ ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ ​ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 ​ 所属专栏:C语言学习 ​ 贝蒂的主页:Betty‘s blog ​ 我们早就学完基本的数据类型,那这些数据类型到底在内存中怎么存储的呢~,今天贝蒂就带大家一起深入学习一下吧 1.1 整型 贝蒂说:“因

    2024年02月02日
    浏览(11)
  • 【C语言】数据在内存中的存储

    【C语言】数据在内存中的存储

    什么叫做浮点数,就是有小数的数据就要浮点数,比如:5.5 6.5 9.0等一些数据就叫浮点数,那么浮点数又是怎么在内存中存放的呢,下面听我一一道来。 浮点型的家族包括:float double long double 我们以以下代码为例比较下浮点数和整型数据内存中的存储是如何的: 打印的结果

    2024年02月07日
    浏览(12)
  • C语言数据在内存中的存储

    C语言数据在内存中的存储

    目录 前言 本期内容介绍 一、数据类型的介绍 1.1类型的意义: 1.2C语言中是否有字符串类型? 1.3类型的基本归类 整型家族: 浮点型(实型)家族: 构造(自定义)类型: 指针类型: 空类型: 二、整型在内存中的存储 2.1原码、反码、补码 总结: 2.2大小端字节序介绍 2.3什

    2024年02月16日
    浏览(10)
  • <C语言> 数据在内存中的存储

    <C语言> 数据在内存中的存储

    C语言中的基本内置类型如下: 类型的意义: 1.使用这个类型开辟内存空间的大小(大小决定了使用范围)。 2.如何看待内存空间的视角。 整型家族: 注意:char有些编译器没有规定是unsigned还是signed 浮点数家族: 构造类型: 指针类型: 空类型: void 表示空类型(无类型)

    2024年02月16日
    浏览(16)
  • C语言:数据在内存中的存储

    C语言:数据在内存中的存储

    在讲解操作符的时候,我们就讲过了下⾯的内容: 整数的2进制表示方法有三种,即 原码、反码和补码 三种表示方法均有 符号位 和 数值位 两部分,符号位都是用0表示“正”,用1表示“负”,而数值位最高位的⼀位是被当做符号位,剩余的都是数值位。 正整数的原、反、

    2024年04月10日
    浏览(16)
  • C语言:数据在内存中的存储形式

    C语言:数据在内存中的存储形式

    关于整数在内存中的存储形式,在博主之前写的文章里已经介绍了!友友们可以去点下面链接去看,这里就不过多介绍。 C语言:进制的转换以及原码、反码、补码 我们以整型在内存中的存储形式为基础,探究后面的内容:整型提升与截断、算数转换、大小端字节序和字节序

    2024年01月23日
    浏览(11)
  • 『C语言』数据在内存中的存储规则

    『C语言』数据在内存中的存储规则

    🔥 博客主页 : 小羊失眠啦. 🔖 系列专栏 : C语言 🌥️ 每日语录 : 精诚所至,金石为开。 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 小羊近期已经将C语言初阶学习

    2024年02月12日
    浏览(15)
  • 【C语言】数据在内存中的存储(一)

    【C语言】数据在内存中的存储(一)

    内置类型: 所占空间的大小: 类型的意义: 使用这个类型开辟空间的大小,决定只能使用的范围。 整型家族: 浮点型家族: 构造类型: 指针类型: 空类型: void表示空类型 通常用于函数的返回类型、函数的参数、指针类型。 变量创建是要在内存开辟空间的,空间的大小

    2024年02月10日
    浏览(15)
  • 【C语言】数据在内存中的存储详解

    【C语言】数据在内存中的存储详解

    我们可以把数据类型想象为一个矩形盒子,int、char 等类型 分别为不同的盒子 可以放着不同大小的东西(数据)(即所占存储空间的大小) 类型的的意义: 使用这个类型开辟内存空间的大小(大小决定了使用范围) 如何看待内存空间的视角。 注意 : 字符在内存中存储的是

    2024年02月13日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包